防抖和节流

223 阅读1分钟

防抖debounce: 多次高频触发某一个事件,小于delay定时器执行间隔则重新计时。

源码:

function debounce(func,delay){
    var timeout;
    return function(e){
        clearTimeout(timeout); //小于delay定时器执行间隔则重新计时
        var context = this,args=arguments;
        timeout = setTimeout(function(){
            func.apply(context,args);
        },delay)
    }
}

// 定义校验器
var validate = debounce(function(e){
    console.log('change', e.target.value, new Date() - 0)
},380)

// 绑定监听
document.querySelector('input').addEventListener('input', validate)

场景: input输入搜索事件,提交按钮的点击事件

节流throtte:多次高频触发某一个事件,限制delay期间必须执行一次事件,没达到delay的事件也算.

源码:

function throttle(fn,threshhold){
    var timeout;
    var start = new Date;
    var threshhold = threshhold || 160;
    return function(){
        var context = this,args=arguments,curr=new Date() - 0;
        clearTimeout(timeout) // 关闭定时器
        if(cur - start >=  threshhold){  //大于时间间隔,直接执行
            fn.apply(context,args);
            start = cur;
        }else{
            timeout = setTimeout(function(){  //小于时间间隔,setTimeOut设置时间间隔执行
                fn.apply(context,args)
            },threshhold)
        }
    }
}

var mousemove = throttle(function(e) {
 console.log(e.pageX, e.pageY)
});

// 绑定监听
document.querySelector("#panel").addEventListener('mousemove', mousemove);

场景:如resize, touchmove, mousemove, scroll。throttle 会强制函数以固定的速率执行。因此这个方法比较适合应用于动画相关的场景。

总结: debounce多次触发,以最后一次触发为准;throttle多次触发以固定间隔触发事件。 debounce限制多长时间才能执行一次,throttle限制多长时间必须执行一次,一个限制上限、一个限制下限。其实这两个方法可以合二为一的。

参考文献: zhuanlan.zhihu.com/p/38313717