如果你在日常开发中,在滚动事件或者窗口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); } };复制代码
如果有错误或者不严谨的地方,请给予指正,十分感谢!