防抖,顾名思义就是防止抖动,名称来源于摄像时会出现抖动和图像模糊情况。而解决方式就是减震、防抖等技术。
代码中的防抖也如此,降低事件的触发频率,防止抖动起来,变得平稳一些。
也就是说,如果该事件不停的触发,我们就要抛弃一部分事件,留下一部分。而防抖的思想就是留下最后一个事件。
其实防抖和节流本质上是对事件频繁触发的约束。若事件被触发两次,而时间间隔又很短
\color{blue}{其实防抖和节流本质上是对事件频繁触发的约束。若事件被触发两次,而时间间隔又很短}
其实防抖和节流本质上是对事件频繁触发的约束。若事件被触发两次,而时间间隔又很短。
则
防抖选择留下
\color{red}{防抖选择留下}
防抖选择留下
后面
\color{blue}{后面}
后面
一个事件
\color{red}{一个事件}
一个事件。
而
节流选择留下
\color{red}{节流选择留下}
节流选择留下
前面
\color{blue}{前面}
前面
一个事件
\color{red}{一个事件}
一个事件。
防抖
防抖的一个问题是,原本可以立即执行的函数,现在需要延迟执行了。
因为当你想要抛弃一些事件,而留下最后一个事件时,你需要让程序知道,谁是最后一个事件。
参数wait则为等待时间。若本次事件在wait时间以内都没有下一次事件,则本次事件为最后一次事件,触发。若在wait时间以内有下一次事件,则表明本次事件并非最后一次事件,则移除该次事件。
// bounce : 抖动 debounce : 去抖动
// 接收两个参数 , fn:要防抖的函数 、 wait:等待时间
function debounce(fn, wait) {
// 既然要延迟执行,就要定时器。而多个事件就会有多个定时器,而只保留最后一个事件,
// 也就只需要保留最后一个定时器,其他的定时器都要清除掉。
let timer = null;
return function () {
//保留上下文,防止要执行的函数中需要用到。因为定时器由window调用,
// 所以一般情况下,this就是window了
let context = this,
args = arguments;
//因为第一次执行该函数时,timer为null,如果timer为true,
//则表示当前这次事件为该时间段的最后一次事件,则清除上一次
if (timer) {
clearTimeout(timer);
timer = null;
}
//将当前事件延迟执行,如果再接收到事件,则下次的事件才是需要保留的事件
//则此次事件也需要被清除。
timer = setTimeout(() => {
// apply函数改变函数的this,参数为数组
fn.apply(context, args);
}, wait);
};
}
节流
因为节流保留首个事件,所以不需要延迟执行,则不需要定时器。
function throttle(fn, delay) {
let preTime = Date.now();
return function () {
let nowTime = Date.now();
if (nowTime - preTime >= delay) {
preTime = Date.now();
fn();
}
};
}