一、what?
防抖 debounce 和节流 throttle 的概念并不是 JS 所特有的。它们是在对函数持续调用时进行不同控制的两个概念。
1、防抖是为了避免用户无意间执行函数多次。比如有些用户喜欢在点击的时候使用 double click 双击,或者就是手抖连续点了两下,这就可能会导致一些意想不到的问题。
2、节流就是连续触发事件但是在n面中只执行一次函数。
二、why?
1、防抖-----优化用户体验:适时反馈,避免UI渲染阻塞,浏览器卡顿,提升页面性能:避免页面渲染卡顿,减少服务器压力,防止恶意触发
2、节流:节流会稀释函数的执行频率。
三、how?
1、防抖可以通过计时器来实现,通过setTimeout来指定一定时间后执行处理函数,如果在这之前事件再次触发,则清空计时器,重新计时。
代码:
简单实现:
function debounce(){
let timerId=null;
return function(...args){
if(timerId)clearTimeout(timerId);
timerId=setTimeout(()=>{
fn.call(this,args);
},wait)
}
}
优化:
function debounce(fn,wait) {
let timerId=null;
let leadingTimerId=null;
return function(...args){
if(timerId){
clearTimeout(timerId);
clearTimeout(leadingTimerId);
timerId=setTimeout(()=>{
fn.call(this,false,args);
leadingTimerId=setTimeout(()=>{
timerId=null;
},wait)
},wait)
}else{
fn.call(this,true,args)
// 为了解决只触发一次,会同时触发首次触发和延时触发的问题引入的特殊值
timerId=-1;
}
}
}
2、节流代码实现:
时间戳:
function throttle(fn,wait){
let pre=0;
return function(){
let now=Date.now();
let _this=this
let args = arguments;
if(now-pre>wait){
fn.apply(_this,args)
pre=now
}
}
}
调用:
content.οnmοusemοve=throttle(count,1000);
定时器:
function throttle(func, wait) {
let timeout;
return function() {
let context = this;
let args = arguments;
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
调用:
content.οnmοusemοve=throttle(count,1000);