Skip to content

手写防抖 debounce

防抖 debounce

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

有这样一个输入框

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

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

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

利用 setTimeout 增加防抖措施

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

进一步优化,封装成函数

js
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,
);

基于 MIT 许可发布