在页面中,懒加载、以及可能频繁触发的事件,通常都会有时间的延迟,这时候频繁的触发会导致事件多次触发而达不到本应出现的效果。这时就需要对事件进行相应的节流或者防抖。
节流与防抖主要是通过在事件函数中,嵌套回调函数,以自由变量的形式缓存时间信息,最后用 setTimeout 来控制事件的触发频率。
节流:取对应时间内第一次触发的
- 节流的思路就是:在规定的某一时间内,不管触发多少次请求,只会取第一次,并且在该时间内,不会进行新的触发响应。
大致代码为:
// cb我们需要包装的事件回调, time是时间间隔
function throttle(cb, time) {
// last为上一次触发回调的时间
let last = 0;
// 将throttle处理结果当作函数返回
return function () {
// 保留调用时的this上下文
let _this = this;
// 保留调用时传入的参数
let args = arguments;
// 记录本次触发回调的时间
let now = new Date().getTime();
// 判断上次触发的时间和本次触发的时间差是否小于给定的时间间隔
if (now - last >= time) {
// 如果时间间隔大于我们设定的时间间隔阈值,则执行回调
last = now;
fn.apply(_this, args);
}
}
}
防抖:取对应时间内最后一次触发的
- 防抖的思路就是:在规定的某一时间内,不管触发多少次请求,只会取最后一次做出响应,前面的请求会被后一次请求覆盖。
大致代码为:
// cb是我们需要包装的事件回调, time是时间间隔的阈值
function throttle(cb, time) {
// last为上一次触发回调的时间, timer是定时器
let last = 0;
let timer = null;
// 将throttle处理结果当作函数返回
return function () {
// 保留调用时的this上下文
let _this = this;
// 保留调用时传入的参数
let args = arguments;
// 记录本次触发回调的时间
let now = new Date().getTime();
// 判断上次触发的时间和本次触发的时间差是否小于时间间隔
if (now - last < time) {
// 如果时间间隔小于我们设定的时间间隔,则为本次触发操作设立一个新的定时器
clearTimeout(timer)
timer = setTimeout(function () {
last = now;
cb.apply(_this, args);
}, time)
} else {
// 如果时间间隔超出了我们设定的时间间隔,那就直接反馈响应,并把last更新
last = now;
cb.apply(_this, args);
}
}
}
小结
节流与防抖都是对频繁触发的事件回调进行优化控制,但是一个是取首次,一个是取最后一次,需要根据具体的需求来使用。