跳到主要内容

手写防抖 debounce

防抖 debounce

  • 监听一个输入框,文字变化后触发 change 事件
  • 直接用 keyup 事件,则会频发触发 change 事件
  • 防抖:用户输入结束活暂停时,才会触发 change 事件

有这样一个输入框

<input type="text" id="input">
<script>const input = document.getElementById('input')</script>

模拟 change 事件,未防抖频繁触发 keyup 事件

// 未防抖,频繁触发 keyup 事件
input.addEventListener('keyup', function () {
console.log(this.value)
})

利用 setTimeout 增加防抖措施

let timer = null
// 利用 setTimeout 增加防抖措施
input.addEventListener('keyup', function () {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
// 模拟触发 change 事件
console.log(this.value)
// 清空定时器
timer = null
}, 500)
})

进一步优化,封装成函数

function debounce(fn, delay = 500) {
// timer 是闭包中
let timer = null
return function () {
if (timer) {
clearTimeout(timer)
}
// 建议使用,防止 this 和 arguments 作用域问题
const self = this
const args = arguments
timer = setTimeout(() => {
// 也其实可以用 fn()
fn.apply(self, args)
timer = null
}, delay)
}
}
input.addEventListener('keyup', debounce(() => {
console.log(input.value)
}), 600)