防抖节流

防抖节流函数:

防抖:

当持续触发事件时, 一定时间内没有再触发,事件处理函数执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时
假如期限值是200ms
1、在200ms 内没有再次触发事件,那么就执行函数;
2、如果在200ms 内再次触发了滚动事件,那么当前计时器取消,重新开始计时;


image.png
function debounce(fn,delay){
let timer = null;
return function(){
   if(timer){
//进入该分支语句,说明当前正在一个计时过程中,并且又触发了相同事件。所以要取消当前的计时,重新开始计时
    clearTimeout(timer)
   }
   timer = setTimeout(fn,delay)
}
}

//防抖debounce代码:
function debounce(fn,delay) {
    var timeout = null; // 创建一个标记用来存放定时器的返回值
    return function (e) {
        // 每当用户输入的时候把前一个 setTimeout clear 掉
       if(timeout){
        clearTimeout(timeout); 
       }
        
        // 然后又创建一个新的 setTimeout, 这样就能保证interval 间隔内如果时间持续触发,就不会执行 fn 函数
        timeout = setTimeout(() => {
            fn.apply(this, arguments);
        }, delay);
    };
}
// 处理函数
function handle() {
    console.log('防抖:', Math.random());
}
        
//滚动事件
window.addEventListener('scroll', debounce(handle,500));

节流函数:

当持续触发事件时,保证一定时间段内只调用一次事件处理函数。

函数防抖(debounce):触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。
函数节流(throttle):高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率。

实现函数节流我们主要有两种方法:时间戳和定时器

image.png
// 节流 (时间戳)
var throttle = function(fn,delay){   
   var pre = Date.now();
   return function(){
     var _this = this;
     var args = arguments;
     var now = Date.now();
     if(now-pre>=delay){
       fn.apply(_this,args);
      pre = Date.now()
     }
   }
}

function handle() {            
  console.log(Math.random());        
}        
window.addEventListener('scroll', throttle(handle, 1000));

当触发事件的时候,我们设置一个定时器,再次触发事件的时候,如果定时器存在,就不执行,直到delay时间后,定时器执行执行函数,并且清空定时器,这样就可以设置下个定时器。

// 定时器
 var throttle = function (fn,delay){
      var timer = null;
      return function (){
        var _this = this;
        var args= arguments;
        if(!timer){
          timer = setTimeout(()=>{
            fn.apply(_this,args)
            timer = null
          },delay)
        }
      }
    }

当remaining<=0时表示该执行事件处理函数了(保证了第一次触发事件就能立即执行事件处理函数和每隔delay时间执行一次事件处理函数)。
如果还没到时间的话就设定在remaining时间后再触发 (保证了最后一次触发事件后还能再执行一次事件处理函数)。
当然在remaining这段时间中如果又一次触发事件,那么会取消当前的计时器,并重新计算一个remaining来判断当前状态。

// 节流throttle代码(时间戳+定时器):
    var throttle = function (fn,delay){
     var timer = null;
     var startTime = Date.now(); // 进来开始的时间
     return function(){
       var currentTime = Date.now();
       var remaining = delay-(currentTime-startTime);
       var _this = this;
       var args = arguments;
       clearTimeout(timer);
       if(remaining<=0){
         fn.apply(_this.args)
         startTime = Date.now()
       }else{
         timer = setTimeout(fn,remaining)
       }

     }
    }

你可能感兴趣的:(防抖节流)