前端JS-手写: 防抖, 节流

50 阅读2分钟

防抖:触发后,开启计时, 如果在规定时间触发,就重置定时器,重新计时,计时结束后触发逻辑

使用场景: 搜索框实时搜索 表单验证 窗口大小调整 状态切换记录最后一次

// 防抖函数实现

   function debounce(func, delay) {
      let timeout;
      return function (...args) {
        console.log('防抖开始');
        clearTimeout(timeout);
        timeout = setTimeout(() => {
          func.apply(this, args)
        }, delay)
      }
    }

节流:在一段时间内,无论事件触发多少次,函数只执行一次

使用场景: 滚动事件 按钮重复点击

​ // 节流函数实现 ​ 时间戳方式:触发后立即执行, 记录当前时间为上一次触发时间,如果再次触发时,当前时间与上一次记录的时间差大于规定的时间,就再次触发事件,时间差小则忽略

    function throttle(func, delay) {
      let lastTime = 0;
      return function(...args) {
        console.log('开始节流 时间戳');
        const now = Date.now();
        if(now - lastTime > delay) {
          func.apply(this, args);
          lastTime = now;
        }
      }
    } 

​ 定时器方式:不立即执行, 等定时器时间结束后再执行函数, 如果定时器没走完,则忽略触发,不发生逻辑

function throttle1(func, delay) {
      let timeout = null;
      return function(...args) {
        console.log('开始节流, 定时');
        if(!timeout) {
          timeout = setTimeout(() =>{
            func.apply(this, args);
            timeout = null;
          }, delay)
        }
      }
    }

demo !!!

<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>按钮示例</title>
</head>
<body>
  <div class="container">
    <button class="interactive-btn" id="actionButton">点击我试试!- 防抖</button>
    <button class="interactive-btn" id="actionButton1">点击我试试!- 节流 时间戳</button>
    <button class="interactive-btn" id="actionButton2">点击我试试!- 节流 定时器</button>
  </div>

  <script>
    const button = document.getElementById('actionButton');
    button.addEventListener('click', debounce(test, 500));
    function test() {
      console.log('点击了按钮, 执行函数');
    }
    // 防抖
    function debounce(func, delay) {
      let timeout;
      return function (...args) {
        console.log('防抖开始');
        clearTimeout(timeout);
        timeout = setTimeout(() => {
          func.apply(this, args)
        }, delay)
      }
    }

    const button1 = document.getElementById('actionButton1');
    button1.addEventListener('click', throttle(test, 1000))
    //节流 时间戳
    function throttle(func, delay) {
      let lastTime = 0;
      return function(...args) {
        console.log('开始节流 时间戳');
        const now = Date.now();
        if(now - lastTime > delay) {
          func.apply(this, args);
          lastTime = now;
        }
      }
    } 

    const button2 = document.getElementById('actionButton2');
    button2.addEventListener('click', throttle1(test, 1000))
    // 节流 定时器
    function throttle1(func, delay) {
      let timeout = null;
      return function(...args) {
        console.log('开始节流, 定时');
        if(!timeout) {
          timeout = setTimeout(() =>{
            func.apply(this, args);
            timeout = null;
          }, delay)
        }
      }
    }

  </script>
</body>

</html>