debounce
触发事件后的一段时间内不再触发,事件会被执行,如果在这段时间内触发,那么需要重新计时
使用场景
- 调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时使用防抖,比如在2s内,不断调整窗口大小,那么不执行resize,直到这2s内不调整了,就可以执行resize了
- 文本编辑器实时保存,当无任何更改操作一秒后进行保存
代码实现
- 把触发的事件封装好,作为参数传入debounce
- 因为是一段时间内不触发,那么就执行,通过使用定时器完成
- 如果在这段时间内触发,就要重新计时,通过使用清除定时器实现
// fn,触发事件
// delay,一段时间内不触发事件
// immediately,立即执行和非立即执行类型
function debounce(fn, wait, immediate) {
let timer;
return function () {
if (timer) clearTimeout(timer);
if (immediate) {
immediate = !immediate; // 取个反
fn.apply(this, arguments);
timer = setTimeout(() => {
timer = null
}, wait)
} else{
timer = setTimeout(() => {
fn.apply(this, arguments);
}, wait)
}
}
}
节流throttle
触发事件后的一段时间内不再触发,事件会被执行,如果在这段时间内触发,那么会被无视
使用场景
- 滚动加载,加载更多或滚到底部监听,只要页面滚动就会间隔一段时间判断一次
- 搜索框,搜索联想功能
代码实现
- 触发函数时,在规定时间内只执行一次, 也是用定时器完成
- 在规定时间内多次触发,会无视掉第一次之后的触发操作
- 因为在规定时间要执行,那么只能生成一个定时器,等规定时间过后,如果继续触发操作,才能生成一个新的定时器,需要一个节流阀来控制定时器的生成
// fn,触发事件
// delay,规定时间内
// immediately,立即执行和非立即执行类型
function throttle(fn, delay, immediate) {
let timer = null
return function () {
const context = this
const arg = arguments
if (immediate) {
fn.apply(context, arg)
if(!timer) {
timer = setTimeout(() => {
// fn.apply(context, arg)
timer = null
}, delay);
}
} else{
if(!timer) {
timer = setTimeout(() => {
fn.apply(context, arg)
}, delay);
}
}
}
}