分类
默认

手写防抖 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)