最简单的 节流防抖_debounce_throttle js

最简单的 节流防抖_debounce_throttle

特别鸣谢:https://segmentfault.com/a/1190000018428170

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>debounce_throttle_防抖_节流</title>
</head>
<body>

  <div style="height: 2000px; padding: 30px;">
    <div style="margin-top: 30px;">
      <h2>1.防抖</h2>
      <hr/>
      > 1.停,才执行 <br/>
      > 2.(优点:能保证最后一次被调用,但只执行一次)
    </div>

    <div style="margin-top: 30px;">
      <h2>2.节流</h2>
      <hr/>
      > 1.动,才执行 <br/>
      > 2.(缺点:最后一次不被调用,但中途会执行多次)
    </div>

    
    <div style="margin-top: 30px;">
      <h2>3.防抖+节流</h2>
      <hr/>
      > 1.停,执行<br/>
      > 2.动,执行 <br/>
      > 3.(优点:几乎完美,缺点:逻辑稍微难一点) <br/>
      > 4.(思路:在节流基础上,加防抖)
    </div>

  </div>

  <script>
    // 监听窗口滚动
    // window.onscroll = debounce(showTop, 1000);

    // window.onscroll = throttle(showTop, 1000);

    window.onscroll = debounce_throttle(showTop, 1000);

    // 要执行的函数
    function showTop(){
      let top = document.documentElement.scrollTop;
      console.error('滚动条位置:', top);
    }

    // 防抖函数
    function debounce(fn, delay){
      let timer = null;
      return function (){
        if(timer){
          // 又有一个调用进来了
          // 如果存在,就清除
          window.clearTimeout(timer);
        }
        // 马上建立下一个延时,只有停下来才执行一次
        timer = setTimeout(fn, delay);
      }
    }

    // 节流函数
    function throttle(fn, delay){
      // 上一次被触发时间
      let lastName = Date.now()
      // 先返回一个函数
      return function(){
        // 当前时间
        let now = Date.now()
        if(now - lastName > delay){
          // 大于间隔时间了,执行
          fn()
          // 关键:本次执行完毕后,将当前时间赋值给上一次时间
          lastName = now;
        }
      }
    }

    // 防抖+节流 (思路:在节流基础上,加防抖)
    function debounce_throttle(fn, delay){
      let timer = null;
      let lastName = Date.now()
      // 先返回一个函数
      return function(){
        let now = Date.now()
        // 如果间隔时间够了(上一次距离这次的时间)
        if(now - lastName > delay){
          // 执行节流
          fn()
          // 交换时间,更新上一次时间
          lastName = now
        }else{
          
          // 如果这时候又有调用进来了,马上清除
          if(timer){
            window.clearTimeout(timer);
            timer = null;
          }

          // 如果时间还不够,保存最后一次,稍后执行
          // 再间隔2秒,如果没触发,就执行:保证最后一次被执行
          timer = setTimeout(fn, delay);
        }
      }
    }
  </script>
  
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值