引入
当用户操作很快,短时间大量触发同一个回调函数,导致算力不必要的消耗,还会导致浏览器的卡顿,这样就导入了节流防抖
节流:在规定的间隔时间范围内不会重复触发回调,在连续触发事件中,执行第一个触发事件时,后面的打断不了第一个,只有当第一次执行结束,才执行下面的
防抖:前面的所有的触发都被取消,最后一次回调在定时结束之后触发,也就是说如果连续快速的触发,只会执行最后一次
实现
节流:
正常操作时,在每次事件被触发时重置定时器。如果在定时器到期之前又有多次事件被触发,则重新设置定时器,并忽略此次事件。如果定时器到期后没有新的事件被触发,则执行相应的代码。(不会重复开启定时)
function throttle(fn, delay) {
// 定义一个定时器
let timer = null;
// 返回一个函数,该函数是被暴露给外面对象使用的,会在事件触发时执行
return function() {
// 获取当前的上下文和参数
let context = this;
let args = arguments;
//当函数第一次调用的时候,timer为null,则跳过if,执行后面代码
//当该次调用没结束前,timer都是由值的,所以只有等第一次结束调用后,才能进行调用
//这保证了,当第一次回调没有执行结束时,后面多次的调用都无法执行
if (timer) {
return;//函数结束
}
//当执行到这步时,timer在计时结束前都是有值的,所以在计时期间如果多次触发都会进入if循环,从而结束调用
//timer可以看作定时器的id,可以通过该id清除该定时器,是每个定时器的身份标志,我们一般在调用结束后清除
timer = setTimeout(function() {
clearTimeout(timer);//清除定时器
timer = null;//计时结束后,我们重新将timer复制为null,为了后续函数也可实现防抖
fn.apply(context, args);
}, delay);
};
}
// 示例:对于一个鼠标移动事件,我们只希望在 200 毫秒内最多触发一次事件
window.addEventListener('mousemove', throttle(function() {
// 此处是事件的处理代码
}, 200));
防抖(debounce)
是指在事件被触发后,如果在计时结束前的这段时间内每次触发此事件,则重新计算时间。在这个时间段内,事件只会执行最后一次。(重新开始)
//防抖
function debounce(fn, delay) {
// 定时器变量
//每次调用该回调都会将定时器重置,所有多次调用只会执行最后一次
let timer = null;
return function() {
// 每次触发函数时,都清除定时器
clearTimeout(timer);
// 重新设定定时器
timer = setTimeout(() => {
fn.apply(this, arguments);
}, delay);
}
}
// 定义一个需要防抖的函数
function handleEvent() {
console.log("触发了防抖事件");
}
// 创建防抖函数,设置延迟为 1000 毫秒
const debounced = debounce(handleEvent, 1000);
// 触发事件
debounced();
debounced();
debounced();