防抖(debounce)的含义:限制函数至少间隔多久执行一次
节流(throttle)的含义:限制函数在某段时间内最多执行一次
防抖和节流的意义:避免页面卡顿,掉帧,提升用户体验,常用在onscroll、onresize这类触发非常频繁的事件上
防抖的实现思路:
- 函数执行过一次后,在n秒内不能再次执行,否则推迟函数执行
- 下一次函数调用将清除上一次的定时器,并用setTimeout重新计时
具体实现:
js
function debounce(fn, ms) {
let timer = null;
return function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, arguments);
}, ms);
}
}适用场景:当窗口大小发生变化时计算新的窗口大小、验证用户输入
总结:利用时间间隔推迟函数的执行
节流的实现思路:
- 函数在n秒内最多执行一次
- 下一次函数调用将清除上一次的定时器
- 若函数执行的时间间隔小于等于规定时间间隔则用setTimeout在规定时间后再执行
- 若函数执行的时间间隔大于规定时间间隔则执行函数,并重新计时
具体实现:
js
function throttle(fn, ms = 300) {
let timer,
startTime = new Date();
return function () {
if (timer) {
clearTimeout(timer);
}
let currentTime = new Date();
if (currentTime - startTime <= ms) {
//小于等于规定时间间隔时,用setTimeout在指定时间后再执行
timer = setTimeout(() => {
fn.apply(this, arguments);
}, ms)
} else {
//重新计时并执行函数
startTime = currentTime;
fn.apply(this, arguments);
}
}
}适用场景:页面滚动图片懒加载
总结:函数节流可以限制函数的执行频率
函数防抖与函数节流的对比:
首先明确一点:不管是函数节流还是函数防抖,我们减少的是事件处理程序的调用频率,而不是事件的调用频率。每次滚动、每次输入都会触发事件。 函数防抖和函数节流都用了闭包封装
当我们用节流函数或防抖函数封装事件处理程序时,要注意两个问题:
- 事件对象的传递
- this的指向