js---节流和防抖

函数防抖:如果有人进电梯(触发事件),那电梯将在10秒钟后出发(执行事件监听器),这时如果又有人进电梯了(在10秒内再次触发该事件),我们又得等10秒再出发(重新计时)。

函数节流 :保证如果电梯第一个人进来后,10秒后准时运送一次,这个时间从第一个人上电梯开始计时,不等待,如果没有人,则不运行

// 函数节流

var throttle = function(fn, interval) { //fn为要执行的函数,interval为延迟时间
  var _self = fn,  //保存需要被延迟执行的函数引用
      timer,  //定时器
      firstTime = true;  //是否第一次调用
  return function() { //返回一个函数,形成闭包,持久化变量
    var args = arguments, //缓存变量
        _me = this;
    if(firstTime) { //如果是第一次调用,不用延迟执行
      _self.apply(_me, args);
      return firstTime = false;
    }
    if(timer) { //如果定时器还在,说明上一次延迟执行还没有完成
      return false;
    }
    timer = setTimeout(function() { //延迟一段时间执行
      clearTimeout(timer);
      timer = null;
      _self.apply(_me, args);
    }, interval || 500);
  };
};
//使用
window.onresize = throttle(function() {
  //你要执行的代码
}, 500);

如果空闲,则可以正常触发方法执行。

如果有一个动作在执行,又触发了一个动作,则直接return。

通过关卡if(!canRun),等于就拿到了通行证。然后下一步的操作就是立马将关卡关上canRun=false。这样,其他请求执行滚动事件的方法,就被挡回去了。

接着用setTimeout规定最小的时间间隔300,接着再执行setTimeout方法体里面的内容,将canRun=true 释放关卡,让下一个执行者执行。

最后,等setTimeout里面的方法都执行完毕,才释放关卡canRun=true,允许下一个访问者进来。

这个函数节流的实现形式,需要注意的是执行的间隔时间是>=300ms。如果具体执行的方法是包含callback的,也可以将canRun=true这一步放到callback中。理解了函数节流的关卡设置重点,其实改起来就简单多了。

函数防抖

function _debounce(fn,wait){

    var timer    = null;
    return function(){
       clearTimeout(timer);
       timer = setTimeout(function(){
           fn();
       },wait);
    }
}
上面的弊端是如果页面太长那fn函数就长时间不能去执行  如果想让fn在一定时间内去执行一次  就需要下面的函数。

function _debounce(fn,wait,time){

       var previous = null; //记录上一次运行的时间

    var timer    = null;

    return function(){
        var now = new Date();
        if(!previous) previous = now;
        //当上一次执行的时间与当前的时间差大于设置的执行间隔时长的话,就主动执行一次
        if(now - previous > time){
            clearTimeout(timer);//执行fn函数也要清除timer要不然 第二次触发的函数就执行了fn
            fn();
            previous = now;// 执行函数后,马上记录当前时间
        }else{
            clearTimeout(timer);
            timer = setTimeout(function(){
                fn();
            },wait);
        }
    }
}
function _log(){
    console.log(1)
}
window.onscroll = _debounce(_log,500)

猜你喜欢

转载自blog.csdn.net/enjoy_sun_moon/article/details/80166315