《节流防抖》

79 阅读1分钟

先说防抖再说节流,我的博客我做主。

防抖

用户触发事件过于频繁,只要最后一次操作。

举例

      <input type="text" />  
      const it = document.querySelector("input");
      it.oninput = function () {
        console.log(this.value);
      };

输入123xyz的时候 浏览器会依次打印当前输入框的值。

image.png

通过防抖,我们可以只打印,最后一次输入操作后,输入框的所有值,从而达到对性能优化的效果。

      const it = document.querySelector("input");
      let t = null;
      it.oninput = function () {
        if (t !== null) {
          clearTimeout(t);  //阻止 setTimeout() 方法执行函数
        }
        t = setTimeout(() => {
          console.log(this.value);
        }, 500);
      };

效果

image.png

代码优化

      const it = document.querySelector("input");

      it.oninput = debounce(function () {
        console.log(this.value);
      }, 500);

      function debounce(fn, delay) {
        let t = null;
        return function () {
          if (t !== null) {
            clearTimeout(t); //阻止 setTimeout() 方法执行函数
          }
          t = setTimeout(() => {
            fn.call(this);  //改变this指向 不然打印的是undefined
          }, delay);
        };
      }

节流

控制高频事件的执行次数

      body {
        height: 2000px;
      }
      window.onscroll = function () {
        console.log(1);
      };

拖拉滚动条 会连续多次的打印1 image.png

我们的目标是: 依旧可以拖拉滚动条,但是降低打印的频率。

      window.onscroll = throttle(function () {
        console.log(1);
      }, 500);

      function throttle(fn, delay) {
        let flag = true;  //一开始是可以执行的
        return function () {
          if (flag) {
            setTimeout(() => {
              fn.call(this);
              flag = true;  //delay时间后 又可以执行了
            }, delay);
          }
          flag = false; //不能执行了
        };
      }

image.png ①一开始可以执行 flag = true

②开始执行任务 setTimeout

setTimeout没结束时(异步操作) 浏览器已经执行了下一句flag = false

在flag是false 和 setTimeout还没执行完这个空档 如果新任务进来了 发现flag目前还是false 那新任务不能执行

setTimeout的任务执行结束 setTimeout里的flag变为true了 再进来新任务可以继续执行

然后重复以上