Js函数防抖、函数节流

应用场景:

  1、当用户提交表单时,多次点击提交按钮

  2、拖拽时的mousemove,window对象的resize、scroll,文字输入等事件触发了大量的回调函数

描述:

  函数防抖: 当调用动作过n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间

      适合多次事件一次响应的情况

  函数节流: 当调用动作过n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作,则不理。若在这n毫秒之后又调用此动作,则进入下一个新周期

      适合大量事件按时间做平均分配触发

function log(){
    console.log(1)
}
function debounce(fn,wait){
    var timer = null;
    return function () {
      var context = this
      var args = arguments
      if (timer) {
          clearTimeout(timer);
          timer = null;
      }
      timer = setTimeout(function () {
          fn.apply(context, args)
      }, wait)
  }
}
window.onscroll = debounce(log,500)

debounce函数存在一个缺点,当我们一直在滚动页面,那log方法就一直不执行。可升级一下上述的防抖方法,如updateDebounce函数

function updateDebounce(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();
            previous = now;// 执行函数后,马上记录当前时间
        }else{
            clearTimeout(timer);
            timer = setTimeout(function(){
                fn();
            },wait);
        }
    }
}
window.onscroll = updateDebounce(log, 500, 2000);
function throttle(fn, time) {
    let _self = fn,
        timer,
        firstTime = true //记录是否是第一次执行的flag

     return function() {
        let 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)
        }, time || 500)
     }
}
window.onscroll = throttle(log,500)

原链接:https://blog.liujiefront.com/2018/04/27/throttle-debounce/

猜你喜欢

转载自www.cnblogs.com/zhanzejuan/p/9187673.html