节流函数

!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>throttle</title>
</head>
<body>
<div style="height:5000px">
  <div id="demo" style="position:fixed;"></div>
</div>
<script>
  var COUNT = 0, demo = document.getElementById('demo');
  function testFn() {demo.innerHTML += 'testFN 被调用了 ' + ++COUNT + '次<br>';}

  var throttle = function (fn, delay, atleast) {
    var timer = null;
    var previous = null;

    return function () {
      var now = +new Date();  
      console.log("now:"+now);

      if ( !previous ) previous = now;
      console.log("previous:"+previous);

      if ( atleast && now - previous > atleast ) {
        fn();
        // 重置上一次开始时间为本次结束时间
        previous = now;
        clearTimeout(timer);
      } else {
        clearTimeout(timer);
        timer = setTimeout(function() {
          fn();
          previous = null;
        }, delay);
      }
    }
  };
  window.onscroll = throttle(testFn, 500);
  //window.onscroll = throttle(testFn, 500, 100);
</script>
</body>
</html>



节流函数的意思:在延迟为 delay 的时间内,如果函数再次触发,则重新计时,这个功能和防抖动是一样的,第三个参数
atleast是一个时间间隔,表示在时间间隔大于 atleast后的一个函数可以立即直接执行。

注意:1.由于触发事件频繁调用函数时,每次都清除上次计时器,所以当滚动事件停止时,过了delay时间,才执行函数,所以,如果一直滚动不停止,只有一次对应函数,这是防抖动函数的缺点;

2.引入节流函数,在规定的时间内,执行对应函数,以上程序中存在闭包两个好处:(1)避免了全局变量污染,将变量封装在函数内部;(2)由于闭包变量不会在函数调用结束从内存清除,持续在内存中,所以previous会保存上次函数调用的值,使得previous成功保存上次函数调用结束的时间;

3.注意变量timer定义的位置,必须在闭包函数外面,否则如果在闭包函数内部,相当于重新定义一个计数器,而timer不会保存函数上次调用值,所以清除无效(清除时,timer=null),相当于计时器叠加,无法达到节流目的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值