标签
note
JS
字数
611 字
阅读时间
3 分钟
概述
js
document.getElementById('test').addEventListener("click", debounce(() => console.log('test')))防抖 指触发事件后在规定时间内回调函数只能执行一次,如果在规定时间内又触发了该事件,则会重新开始算规定时间。
简单总结就是 延时执行 最后一次触发。
节流 则是防抖实现的效果之一,减少请求资源
区别
一个是多次点击,只触发一次 (回城
一个是一个时间段,只触发一次(技能 cd
实现代码
通过定时器将回调函数进行延时.如果在规定时间内继续回调,发现存在之前的定时器,则将该定时器清除,并重新设置定时器.
js
// 第一版
// 缺点:函数的 this 指向了 window,应该指向 container
function debounce1(fn, delay) {
let timer = null
return function() {
clearTimeout(timer);
timer = setTimeout(fn, delay)
}
}
// 第二版
// 缺点:函数的事件对象 event 变成了 undefined
function debounce2(fn, delay) {
let timer = null
return function() {
clearTimeout(timer)
// console.log(this) // 这里的this还是指向容器的
timer = setTimeout(() => {
fn.call(this) // 绑定this
}, delay)
}
}
// 第三版(解决 event 事件对象问题)
function debounce3(fn, delay) {
let timer = null
return function() {
clearTimeout(timer)
timer = setTimeout(() => {
fn.call(this, arguments) // 传递参数
}, delay)
}
}
// 第四版(立刻执行,停止触发 n 秒后,才可以重新触发执行)
function debounce4(fn, delay, immediate) {
let timer = null
return function() {
if (timer) clearTimeout(timer)
if (immediate) {
// 如果已经执行过,不再执行
var callNow = !timer
timer = setTimeout(() => {
timer = null
}, delay)
if (callNow) {
fn.apply(this, arguments)
}
} else {
timer = setTimeout(() => {
fn.apply(this, arguments)
}, delay)
}
}
}应用场景
两个条件:
1,如果客户连续的操作会导致频繁的事件回调 (可能引起页面卡顿).
2,客户只关心 "最后一次" 操作 (也可以理解为停止连续操作后) 所返回的结果. 例如:
- search 搜索联想,用户在不断输入值时,用防抖来节约请求资源。
- 不断的调整浏览器窗口大小会不断的触发 resize 事件,用防抖来让其只触发一次。
- 按钮点击: 收藏,点赞,心标等