防抖与节流

防抖与节流(debounce + throttle)

防抖 debounce

在很多情况下都需要防抖处理,例如,用户的输入提示,用户每次没输入一个字都会发出请求,获取建议词,但是在连续输入的时候,中间有很多次请求是没必要的。这在之前的一篇博客中提过了,为了防止这种情况,对输入事件的处理函数进行防抖处理。

现在,看看另一种情况 , 连续滚动页面,例如,在做图片懒加载的时候,连续的滚动,会触发多次加载图片函数,但是中间的那些也是没有必要的,因为最后那次事件会把所有满足条件的图片都加载,那前面执行的那些,就给浏览器白白制造了工作量,降低了页面流畅性。

现在用防抖来处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
window.addEventListener("scroll",debounce(scrollHandler)); // 防抖处理

window.addEventListener("scroll",scrollHandler); // 无防抖处理

function scrollHandler(){
// 滚动 触发的事件
console.log("滚动了!");
}
// 采用了闭包,在连续触发滚动事件的情况下,前一次的事件中创建的timer因为闭包会被保留,下一次的事件如果离上一次小于300ms就会删除timer,这样一来上一次事件就不会执行func,因为timer已经被清除了,以此类推,只有最后一个才会执行handler方法。
function debounce(func,time){
var timer ;
return function(){
clearTimeout(timer);
timer = setTimeout(func,time||300);
}
}

节流 Throttling

其实 防抖函数 在输入提示的情况下最适合,但在懒加载上还是有一定缺陷,因为它可能很长时间不加载,如果你一直滚动的话。但是需要在滚动过程中偶尔也加载一次。

这时候需要用 节流 函数了,它能保证在 一定时间内 至少执行一次处理函数.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
window.addEventListener("scroll",throttle(scrollHandler,500,1000)); // 防抖处理


function scrollHandler(){
// 滚动 触发的事件
console.log("滚动了!");
}
// 在防抖函数的基础上 , 结合了防抖的功能
function throttle(func, wait, mustRun) {
var timeout,
startTime = new Date();

return function() {
var context = this,
args = arguments,
curTime = new Date();

clearTimeout(timeout);
// 如果达到了规定的触发时间间隔,触发 handler
if(curTime - startTime >= mustRun){
func.apply(context,args);
startTime = curTime;
// 没达到触发间隔,重新设定定时器
}else{
timeout = setTimeout(func, wait);
}
};
};

以上都是简单实现 其实可以直接使用 underscore 中封装好的 现成的方法。