实现防抖(debounce)
- 防抖函数的设计思路是:不允许高频率地调用事件处理程序,使用延时程序延时执行事件处理程序,如果已经存在待执行的时间处理程序函数,则重新计时。
- 以监听
scroll
为例,当滚轮事件触发频率低于1000ms时,不调用事件处理程序(删掉延迟触发函数的timer),当高于1000ms时,任其调用。
function showTop() {
let mode = document.compatMode == 'CSS1Compat' ? 'documentElement' : 'body';
// 只有IE6以下的浏览器会使用怪异模式,返回‘backCompat'
let scrollTop = document[mode].scrollTop;
console.log(scrollTop);
}
function debounce(fn, delay) {
let timer = null;
return () => {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn();
}, delay);
}
}
window.onscroll = debounce(showTop, 1000);
实现节流(throttle)
- 节流函数的设计思路是:高频率事件触发条件下,限制事件处理程序的调用频率。通过设置标识符或时间戳的方式检查是否满足事件触发频率高于所设置的间隔时间,如果满足就允许执行事件处理程序,如果不满足则不允许执行。
- 通常一次事件触发就会调用一次事件处理程序,我们可以令其在指定时间内只调用一次函数。
- 同样以
scroll
事件为例,设置其在1000ms内无论触发多少次事件,都只能调用一次事件处理程序。
通过设置标识符来实现节流
function throttle(fn, delay) {
let valid = true;
// 代表程序可用
return () => {
if (!valid) return;
// 程序不可用就直接退出
valid = false;
// 第一次触发事件时程序可用,一旦用后立即将程序设定为不可用
setTimeout(() => {
fn();
valid = true;
// 程序执行结束后,设定为可用,开启下一周期
}, delay)
}
}
通过检查时间戳来实现节流
function throttle(fn, delay) {
let timeStamp = Date.now();
return () => {
if (Date.now() - timeStamp < delay) {
return;
} else {
timeStamp += delay;
fn();
}
}
}
参考链接