之前研究过防抖节流,翻看别人博客多少有点迷糊,自己写了个demo算是初步捋清楚了防抖节流基本作用,搞明白了基础的写法,特此分享下。
首先创建一个页面,画两个input输入框,一个实现防抖,一个实现节流。
<div>防抖<input class='inputAntiShake'></input></div>
<div>节流<input class='inputThrottle'></input></div>
1 防抖
获取防抖输入框,尝试不作防抖的效果
let num = 0;
let inputAnt = document.querySelector('.inputAntiShake')
inputAnt.addEventListener('input', (e) => {
num++;
console.log(`发起请求,${num}次`)
})

可见,输入一个字符就会执行一次监听的事件,在开发过程中会造成资源的浪费。
现在我们加上防抖功能
let num = 0;
let inputAnt = document.querySelector('.inputAntiShake')
inputAnt.addEventListener('input', antiShake(demo, 2000))
function demo() {
num++;
console.log(`发起请求,${num}次`)
}
function antiShake(event, wait) {
let timeOut = null;
return function () {
if (timeOut) clearTimeout(timeOut);
timeOut = setTimeout(event, wait)
}
}
同样也是包装了事件的计数功能,但是触发的次数并不一样了

同样输入了7个字符,但是事件监听器只执行了一次函数。
antiShake函数使用了闭包原理,把timeOut变量存入了内存中,timeout的值为setTimeout,因此需要等待wait时间才能执行demo方法,在wait时间之间如果有新的事件触发,就会不断地执行clearTimeout重新开始计时,直到在wait时间内没有事件继续触发,才会输出结果。
这就是防抖的基本原理。
2 节流
获取防抖输入框,尝试不作防抖的效果。
let num = 0;
let inputThr = document.querySelector('.inputThrottle')
inputThr.addEventListener('input', (e) => {
num++;
console.log(`发起请求,${num}次`)
})

同样,输入了七个字符就会触发其次事件。
现在我们加上节流功能。
let num = 0;
let inputThr = document.querySelector('.inputThrottle')
inputThr.addEventListener("input", throttle(demo, 2000))
function demo() {
num++;
console.log(`发起请求,${num}次`)
}
function throttle(event, wait) {
let timer = null;
return args => {
if (!timer) {
timer = setTimeout(
() => {
event();
timer = null;
}, wait
);
}
}
}

这次触发事件的次数也不一样了,在2秒之内时间最多只会被触发一次,输入了15个字符,却只触发了3次事件。
这次在throttle函数内使用了闭包,使事件一定会在wait时间之后执行,且执行后会立刻把timer重置,进入下一个setTimeout,与setInterval相似。
不论用户触发了多少次时间,在wait时间内都只会执行一次,大大节省了资源,通常用在防止重复提交表单以及监听频繁事件上。