js中防抖节流

防抖: 事件在n秒后执行,如果在n秒内被再次出发,会重新计算时间,直到n 秒后才执行。简单点就是一个事件,一个事件在n秒内被再次触发,事件不会执行,只有过了n秒才执行

  • 防抖应用:scroll滚动事件的出发;
  • 网络请求一些应用;
  • 表单验证
  • 按钮提交事件
  • 浏览器窗口缩放
  • 搜索框输入

还是看代码吧

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .container {
        width: 100%;
        height: 200px;
        background-color: rgb(166, 187, 184);
        text-align: center;
        line-height: 200px;
        background-size: 30px;
      }
    </style>
  </head>
  <body>
    <div class="container"></div>
    <script>
      let dv1 = document.querySelector(".container");
      let counter = 0;

      function doSome() {
        dv1.innerHTML = counter++;
      }
      dv1.addEventListener('mousemove', doSome)
  </script>
  </body>
</html>

当鼠标在这个盒子移动会频繁出发这个事件,影响性能,

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .container {
        width: 100%;
        height: 200px;
        background-color: rgb(166, 187, 184);
        text-align: center;
        line-height: 200px;
        background-size: 30px;
      }
    </style>
  </head>
  <body>
    <div class="container"></div>
    <script>
      let dv1 = document.querySelector(".container");
      let counter = 0;

      function doSome() {
        dv1.innerHTML = counter++;
      }
      // dv1.addEventListener('mousemove', doSome)
      dv1.addEventListener('mousemove', debounce(doSome,300))

      function debounce(fun, wait) {
        let timer = null;
        return function () {
          clearTimeout(timer);
          timer = setTimeout(() => {
            fun.apply(this, arguments);
          }, wait);
        };
      }
    </script>
  </body>
</html>

 2节流: 如果你持续触发事件,每隔一段时间,只执行一次事件。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .container {
        width: 100%;
        height: 200px;
        background-color: rgb(166, 187, 184);
        text-align: center;
        line-height: 200px;
        background-size: 30px;
      }
    </style>
  </head>
  <body>
    <div class="container"></div>
    <script>
      let dv1 = document.querySelector(".container");
      let counter = 0;

      function doSome() {
        dv1.innerHTML = counter++;
      }
      // dv1.addEventListener('mousemove', doSome)
      // dv1.addEventListener("mousemove", debounce(doSome, 300));
      dv1.addEventListener('mousemove',throttle(doSome, 1000))
      // 2、节流函数体
      function throttle(fn) {
        // 4、通过闭包保存一个标记
        let canRun = true;
        return function () {
          // 5、在函数开头判断标志是否为 true,不为 true 则中断函数
          if (!canRun) {
            return;
          }
          // 6、将 canRun 设置为 false,防止执行之前再被执行
          canRun = false;
          // 7、定时器
          setTimeout(() => {
            fn.call(this, arguments);
            // 8、执行完事件(比如调用完接口)之后,重新将这个标志设置为 true
            canRun = true;
          }, 1000);
        };
      }
    </script>
  </body>
</html>

// 2、防抖功能函数,接受传参
    function debounce(fn) {
      // 4、创建一个标记用来存放定时器的返回值
      let timeout = null;
      return function() {
        // 5、每次当用户点击/输入的时候,把前一个定时器清除
        clearTimeout(timeout);
        // 6、然后创建一个新的 setTimeout,
        // 这样就能保证点击按钮后的 interval 间隔内
        // 如果用户还点击了的话,就不会执行 fn 函数
        timeout = setTimeout(() => {
          fn.call(this, arguments);
        }, 1000);
      };
    }

引用:https://juejin.im/post/5c87b54ce51d455f7943dddb#heading-3 

posted @ 2020-04-14 23:58  性感的沙皮  阅读(251)  评论(0编辑  收藏  举报