前端经典练习: 1. 手写防抖, 节流

40 阅读1分钟

防抖:事件触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时

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

// 防抖函数实现

   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>