防抖

函数防抖:短时间多次触发同一事件,只执行 最开始 或 最后 一次操作。

function debounce(func, ms = 1000) {
  let timer;
  return function(...args) {
    console.log(args);
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      func.apply(this, args);
    }, ms);
  };
}
const task = () => {console.log('run task')};
const debounceTask = debounce(task, 1000);
window.addEventListener('click', debounceTask);  // click 可以换成 scroll

 防抖原理:

  就 click 来说,如果 1s 内,点击很多次的话,debounceTask(指匿名函数) 就会执行很多次。那 task 函数也会多次调用,造成不必要的浪费。如图说明吧:

 

对 debounce 函数返回的匿名函数中 args 参数(这里可忽略)的存在作出说明:
  const debounceTask = debounce(task, 1000) 其实返回的是匿名函数。

点击页面触发 window.addEventListener('click', debounceTask) 事件,debounceTask 会执行。

这里 debounceTask 没有传递参数,打印 args 会看到有个事件对象,这里的原因是因为:
  在浏览器中,如果函数执行没有传递参数,会默认有个浏览器事件对象作为参数,如监听的是点击 click 事件的话 args 就是 [PointerEvent]

将 click 换成 scroll,如果在函数不防抖,要执行很多次了~

 

完整案例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, maximum-scale=1, minimum-scale=1,initial-scale=1"/>
  <title>Title</title>
  <style>
    body {
      overflow: scroll;
      height: 10000px;
      border: 2px solid;
    }

    input {
      margin-left: 20px;
      width: 20px;
      height: 20px;
    }
  </style>
</head>
<body>
<p>函数防抖:短时间多次触发同一事件,只执行最后或最开始的一次。</p>
<p>这里以点击事件做测试</p>
<input type="checkbox"/>
<input type="checkbox"/>
<input type="checkbox"/>
<input type="checkbox"/>
<input type="checkbox"/>

<script>
function debounce(func, ms = 1000) {
  let timer;
  console.log("匿名函数前的 timer", timer);
  return function(...args) {
    console.log("匿名函数后的 timer", timer);
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      func.apply(this, args);
    }, ms);
  };
}
const task = () => {console.log('run task')};
const debounceTask = debounce(task, 1000);
window.addEventListener('click', debounceTask);
</script>
</body>
</html>
完整案例

 

<script>

    /*
    节流:函数在一段时间内多次调用,仅第一次有效。
    防抖:函数在一段时间内多次调用,仅最后一次有效。
    * */

    // window.addEventListener('scroll', throttle2(scrollFun, 1000));
    window.addEventListener('scroll', debounce(scrollFun, 500));

    function scrollFun(e) {
      console.log('窗口大小改变了');
    }

    /* 节流—时间戳方式 */
    function throttle(func, delay) {
      var last = 0;
      return function () {
        var now = Date.now();
        /*
        一开始滚动的时候就执行,后面是隔一定秒数再执行,再滚动时,先获取的 now 值,间隔时间 超过 delay 时间的话 ,now > delay + last,执行函数。
        * */
        if (now >= delay + last) {
          func.apply(this, arguments);
          last = now;
        } else {
          console.log('********** wait ');
        }
      }
    }

    /* 节流—定时器方式 */
    function throttle2(func, delay) {
      var timer = null;
      return function () {
        if(!timer) {
          func.apply(this, arguments);
          timer = setTimeout(function() {
            timer = null;
          }, delay);
        } else {
          console.log('********** wait ');
        }
      }
    }

    /* 防抖 */
    function debounce(func, delay) {
      var timeout;
      return function () {
        clearTimeout(timeout);
        timeout = setTimeout(() => {
          console.log('run')
          func.apply(this, arguments);
        }, delay);
      }
    }
  </script>
节流防抖

 

 

 

不开始最难,迟迟不开始变得又难又慌~

posted @ 2022-05-07 16:26  し7709  阅读(323)  评论(0编辑  收藏  举报