节流防抖函数的实现

138 阅读1分钟

js防抖与节流的区别与相同点:

都是为了防止统一内多次执行事件,消耗浏览器性能。

不同点:防抖是在同一时间段执行多次,那么就清楚前面的事件,执行性最后一次;节流是在同一时间段,如果事件没有超过指定的时间间隔那么就不去执行下一次;

防抖与节流的常见应用 1:按钮的点击提交; 2:在input输入框中执行输入搜索事件;

代码如下

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div
      id="content"
      style="
        height: 150px;
        line-height: 150px;
        text-align: center;
        color: #fff;
        background-color: #ccc;
        font-size: 80px;
      "
    ></div>
    <script>
      let num = 1;
      const content = document.getElementById("content");
      function count() {
        console.log(1);
        content.innerHTML = num++;
      }
  //立即执行一次然后节流
      function throttle(fn, delay) {
        let prev = 0;
        return function () {
          let context = this;
          let arg = [...arguments];
          if (Date.now() - prev > 0) {
            fn.apply(context, arg);
            prev = Date.now();
          }
        };
      }
   //节流
      function immediatelyThrottle(fn, delay) {
        let timer;
        return function () {
          let context = this;
          let arg = [...arguments];
          if (!timer) {
            timer = setTimeout(() => {
              fn.apply(context, arg);
              timer = null;
            }, delay);
          }
        };
      }
      
      //防抖
      function immediatelyDebounce(fn,delay){
        let timer;
        return function(){
          if(timer)clearTimeout(timer)
          let context = this;
          let arg = [...arguments];
          timer=setTimeout(() => {
            fn.apply(context,arg)
          }, delay);
        }
      }

  //立即执行一次然后防抖
      function debounce(fn,delay){
        let timer;
        return function(){
          let context = this;
          let arg = [...arguments];
          let callNow=!timer
          if(timer)clearTimeout(timer)
          timer=setTimeout(() => {
             timer=null
          }, delay);
        }
        if(callNow)fn.apply(context,arg)
      }

      content.onmousemove = debounce(count, 1000);
    </script>
  </body>
</html>



在项目上完全可以不依赖lodash这样的库来实现,可以自己写,用于减小打包体积,加快首页加载速度,vue2中可以通过自定义指令来封装,vue3可以通过自定义ref来实现。