防抖和节流函数介绍
二者的共同点是都是限制触发频率(都是通过定时器实现)。
假如让我们设计一个全屏滚动效果,优化可以通过下面方式入手:
- 更改页面大小时,通过防抖(debounce)函数限制
resize
事件触发频率。 - 滚动/滑动事件触发时,通过节流(throttle)函数限制滚动/滑动事件触发频率。
二者的区别:
防抖函数工作时,如果在指定的延迟事件内,某个事件连续触发,那么绑定在这个事件上的回调函数永远不会触发,只有在延迟时间内,这个事件不再触发,对应的回调函数才会执行。防抖函数非常适合于改变窗口大小这一事件,也符合拖动到位以后再触发事件,如果一直拖不停,始终不触发事件。
节流函数是在延迟时间内,绑定在事件上的回调函数只能触发一次,即便是在延迟时间内连续触发事件,也不会阻止在延迟时间内有一个回调函数执行。并且节流函数允许我们指定回调函数是在延迟时间开始时还是结束时执行
鉴于节流函数的上述特点,尤其适合优化滚动/滑动事件:
- 可以限制频率;
- 不会因为滚动/滑动事件太灵敏(在延迟时间内不断触发)导致注册在事件上的回调函数无法执行;
- 可以设置在延迟时间开始时触发回调函数,从而避免用户感到操作之后的短暂延时。
代码:
// 防抖
// params:
// method:回调函数 context:上下文 event:传入事件 delay:延迟函数
debounce(method, context, event, delay) {
clearTimeout(method.tId);
method.tId = setTimeout(() => {
method.call(context, event);
}, delay);
}
// 节流
// params:
// method:回调函数 context:上下文 delay:延迟函数
throttle(method, context, delay){
let wait = false;
return function(){
if(!wait){
method.apply(context, arguaments);
wait = true;
setTimeout(()=>{
wait = fasle;
}, delay);
}
};
}