什么时候用防抖,是在高频事件触发结束一段时间后,再去执行回调,否则在这段时间内再次触发,就会重新计时。
——————防抖——————
举例子是进电梯,一直进人电梯就一直关不上门,等一段时间没人进来才能关闭电梯门
再比如:
1、联想词,等用户输入完一段时间不动后,才被认为是输入结束
2、页面滚动加载,等滚动停止一段时间后,再去加载下一页,不然就会一直去触发
3、按钮点击多次防止重复提交,停止频繁点击后再提交
function debounce(cb, ms) {
let timer = null;
return function () {
// 如果存在定时器说明还有任务在执行,清除重置
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
timer = null;
clearTimeout(timer);
cb();
}, ms);
};
}
const handleResize = () => {
console.log("执行事件");
};
window.addEventListener("resize", debounce(handleResize, 2000));
写代码时我犯了两个错误,
第一个直接在debounce(handleResize, 2000)的handleResize处写了箭头函数, 这样会立即执行该函数,要写函数的引用,不是函数本身,函数参数会去立即执行的。
第二个错误是debounce函数没有返回函数,错了,因为addEventListener监听事件要写函数回调才会去执行
——————节流——————
节流主要注意频率问题,需要隔段时间执行一次的就需要节流。
比如说,鼠标移动追踪,每100ms去追踪一次,以及游戏技能冷却等
function throttle(cb, ms) {
// 如果触发了怎么办,发现在上一个事件设置的timer还在,说明时间没到,不触发
let timer = null;
return function (...args) { // args可以捕获事件触发时传递的所有参数
if (timer) return;
timer = setTimeout(() => {
cb.apply(this, args);
timer = null;
}, ms);
};
}
const handleMove = (event) => {
console.log("移动", event.clientX, event.clientY);
};
window.addEventListener("mousemove", throttle(handleMove, 2000));
cb.apply(this, args);这句需要拿出来单独说一下,其实也可以就这么写cb(...args) 主要是看回调函数cb中有没有需要用到修改this指向的地方。
完。。。