高频事件触发时的防抖与节流

336 阅读1分钟

防抖与节流

当事件高频触发后,默认事件会立即执行,然而多次重复执行事件函数会带来客户端性能上的问题,因此提供了函数防抖与节流两种方案来解决事件高频触发这样一个问题。

防抖(debounce)

理解

函数防抖指的是当事件触发后,事件不立即执行,固定一段时间后的执行该事件,如果在等待的这段时间内继续触发该事件则重新开始等待

手写防抖

<button id="btn">点击</button>

<script>
  const btn = document.querySelector("#btn");

  btn.addEventListener("click", debounce(fn, 2000));

  function fn() {
    console.log("点击了");
  }

  function debounce(fn, time) {
    let timeOut = null;
    return function () {
      clearTimeout(timeOut);
      timeOut = setTimeout(fn, time);
    };
  }
</script>

节流(throttle)

理解

函数节流指的是高频事件触发,n 秒内只执行一次

手写节流

<script>
  setInterval(() => {
    console.log("current Time", new Date().getSeconds(), "s");
  }, 1000);

  //节流
  window.onresize = throttle(fn, 2000);

  function fn() {
    console.log("监听到页面尺寸变化");
  }

  function throttle(fn, time) {
    let canRun = true;
    return function () {
      if (!canRun) return;
      canRun = false;
      setTimeout(() => {
        fn();
        canRun = true;
      }, time);
    };
  }
</script>

整份代码

<script>
  setInterval(() => {
    console.log("current Time", new Date().getSeconds(), "s");
  }, 1000);

  //防抖
  // window.onresize = debounce(fn, 2000)

  //节流
  window.onresize = throttle(fn, 2000);

  function fn() {
    console.log("监听到页面尺寸变化");
  }

  function throttle(fn, time) {
    let canRun = true;
    return function () {
      if (!canRun) return;
      canRun = false;
      setTimeout(() => {
        fn();
        canRun = true;
      }, time);
    };
  }

  function debounce(fn, time) {
    let timeOut = null;
    return function () {
      clearTimeout(timeOut);
      timeOut = setTimeout(fn, time);
    };
  }
</script>