防抖

321 阅读2分钟

如果你在日常开发中,在滚动事件或者窗口resize事件时需要做一个复杂的计算,如果不限制事件处理函数调用的频率,会加重浏览器的负担,造成性能浪费甚至页面卡顿。此时我们可以采用防抖(debounce)和节流(throttle)的方式来减少调用频率,同时又不影响实际效果,本文主要讲解防抖。

所谓防抖,就是事件一直被触发的话,第一次触发立即执行,但是触发间隔小于设置的延迟时间(delay)时,函数不会被调用,只有触发间隔大于等于设置的延迟时间,函数才会被调用。

接下来我们理一下思路:

1. 该函数要有一个参数为事件合理触发后要调用的函数,我们定义为fn;

2. 第二个参数为调用该函数的对象,即函数执行时的this指向,我们定义为context;

3. 第三个参数为调用该函数时要传入的参数,我们定义为数组args;

4: 第四个参数为延迟时间,我们定义为delay;

注:函数内部我们还会给fn定义两个属性,用来接收setTimeout的fn.debounceATimerId和用来表示是否第一次点击的fn.debounceFirst

代码如下:

let debounce = (fn,context,args,delay=500) => {
  // 每次事件触发,如果存在fn.debounceATimerId,清除fn.debounceATimerId,为的是如果触发间隔小于延迟时间,则取消setTimeout
  if(fn.debounceATimerId){
    clearTimeout(fn.debounceATimerId)
  }
  // 判断fn.debounceFirst是否为true
  if(fn.debounceFirst){
    // 说明事件不是第一次被触发
    // 设置fn.debounceATimerId 接收 setTimeout delay 毫秒后调用fn,并绑定this为context,参数为args
    fn.debounceATimerId = setTimeout(() =>{fn.apply(context,args)},delay);
  }else{
    // 说明事件第一次被触发
    // 设置fn.debounceFirst为true
    fn.debounceFirst = true;
    // 调用fn,并绑定this为context,参数为args
    fn.apply(context,args);
  }
};


如果有错误或者不严谨的地方,请给予指正,十分感谢!