一、防抖(debounce)
1.概念
对于短时间内连续触发的事件,防抖就是为了处理这种事件而产生的函数,规定在一定时间内,只执行一次函数
比如说连续点击按钮触发的事件、监听窗口的滚动事件
// 调用 debounce 会返回一个包装器。
// 当它被调用时,它会安排一个在给定的 ms 之后对原始函数的调用,并取消之前的此类超时。
function debounce(func, ms){
let timer;
let wrapper = function(){
clearTimeout(timer);
timer = setTimeout(() => func.apply(this, arguments),ms)
}
return wrapper;
}
二、节流(throttle)
根据防抖的思路,只要用户不停触发,那么事件就会一直不触发,如果希望无论用户是否持续触发,一段时间后,都执行这个事件函数,就用到了节流。
节流函数:类似控制阀门一样定期开放的函数,也就是让函数执行一次后,在某个时间段内暂时失效,过了这段时间后再重新激活
function throttle(func, ms){
let isThrottle = false,
savedArgs,
savedThis; // 初始化 节流状态为false,this、args为空
function wrapper(){
if(isThrottle){ // 2. 处于节流状态为true,存储下 this 和 arguments
savedArgs = arguments;
savedThis = this;
return;
}
func.apply(this, arguments); // 1. 第一次调用只执行这两句
isThrottle = true; // 第一次执行函数过后节流状态设置为true
setTimeout(function(){
isThrottle = false; // 3. ms 后节流状态置为false
if(savedArgs){ // 存在参数时,调用包装器函数
wrapper.apply(savedThis, savedArgs);
savedArgs = savedThis = null; // this 及 args 重置为空
}
}, ms)
}
return wrapper;
}
三、应用场景
搜索框input事件
,例如要支持输入实时搜索可以使用节流
方案(间隔一段时间就必须查询相关内),或者实现输入间隔大于某个值(如500ms),就当做用户输入完成,然后开始搜索,具体使用哪种方案要看业务需求。- 页面
resize事件
,常见于需要做页面适配的时候。需要根据最终呈现的页面情况进行dom渲染(这种情形一般是使用防抖
,因为只需要判断最后一次的变化情况)
思考总结