防抖节流

作者: Lyan_2ab3 | 来源:发表于2020-07-01 17:30 被阅读0次

    防抖节流函数:

    防抖:

    当持续触发事件时, 一定时间内没有再触发,事件处理函数执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时
    假如期限值是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)
           }
    
         }
        }
    

    相关文章

      网友评论

        本文标题:防抖节流

        本文链接:https://www.haomeiwen.com/subject/iupsohtx.html