前端优化 防抖与节流

事件优化

防抖与节流

防抖:

所谓防抖,就是把触发非常频繁的事件合并成一次去执行。即在指定时间内只执行一次回调函数,如果在指定的时间内又触发了该事件,则回调函数的执行时间会基于此刻重新开始计算。

指触发事件后在n秒内只执行一次,若在n秒内再次触发则重新计算

节流:

所谓节流,是指频繁触发事件时,只会在指定的事件段内执行事件回调,即触发事件间隔大于等于指定的事件才会执行回调函数。

连续发生的事件在n秒内只执行一次函数

为什么要防抖或节流
  • 及时查询时,减少服务器压力。
  • 频繁执行DOM操作、资源加载等重行为,导致UI停顿甚至浏览器崩溃

需求是以一定的频率执行后续的处理。

实现

防抖

只要触发,就会清除上一个计时器,又注册新的一个计时器。直到停止触发wait时间后,才会执行回调函数。

不断触发事件,就会不断重复这个过程,达到防止目标函数过于频繁的调用的目的。

function debounce(func, wait) {
      let timeout;
      return function () {
        if (timeout) window.clearTimeout(timeout);
        timeout = window.setTimeout(function () {
          func.apply(this, arguments);
        }, wait);
      };
    }

调用apply改变传入的func方法中的this指向,指向绑定事件的DOM元素。

节流

只要触发,只会在当前计时器为空时,注册计时器。

不断触发事件,只会在固定的事件间隔触发。

setTimeout
function throttle(func, wait) {
      let timeout;
      return function () {
        if (!timeout) {
          timeout = window.setTimeout(function () {
            func.apply(this, arguments);
            timeout = null;
          }, wait);
        }
      };
    }
时间戳
 function throttleTime(func, wait) {
      let prev = 0;
      return function () {
        let now = Date.now();
        if (now - prev > wait) {
          func.apply(this);
          prev = now;
        }
      };
    }

所有

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=<device-width>, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button id="bt1">防抖</button>
    <button id="bt2">节流</button>
  </body>
  <script>
    // 防抖
    function debounce(func, wait) {
      let timeout;
      return function () {
        if (timeout) window.clearTimeout(timeout);
        timeout = window.setTimeout(function () {
          func.apply(this, arguments);
        }, wait);
      };
    }
    // 节流
    function throttle(func, wait) {
      let timeout;
      return function () {
        if (!timeout) {
          timeout = window.setTimeout(function () {
            func.apply(this, arguments);
            timeout = null;
          }, wait);
        }
      };
    }
    function throttleTime(func, wait) {
      let prev = 0;
      return function () {
        let now = Date.now();
        if (now - prev > wait) {
          func.apply(this);
          prev = now;
        }
      };
    }
    let bt1 = document.getElementById("bt1");
    let bt2 = document.getElementById("bt2");
    bt1.onclick = debounce(function () {
      console.log(1);
    }, 1000);
    bt2.onclick = throttleTime(function () {
      console.log(2);
    }, 1000);
  </script>
</html>
posted @ 2020-09-22 14:25  lemon-Xu  阅读(1250)  评论(0编辑  收藏  举报