chenshuhong / fullstack

我的全栈路线思维导图以及日常知识记录
MIT License
0 stars 0 forks source link

JavaScript防抖与节流 #4

Open chenshuhong opened 4 years ago

chenshuhong commented 4 years ago

防抖 触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间

function debounce(func,wait,immediate){
  var timeout,result
  var debounced =  function(){
    var context = this
    var args = arguments
    clearTimeout(timeout)
    if (immediate){
      var callNow = !timeout;
      timeout = setTimeout(function(){
        timeout = null;
      }, wait)
      if (callNow) result = func.apply(context, args)
    } else {
      timeout = setTimeout(function(){
        func.apply(context,args)
      },wait)
    }
    return result
  }

  debounced.cancel = function(){
    clearTimeout(timeout)
    timeout = null
  }

  return debounced
}

节流 高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率

/**
 * 双剑合璧版本
 * @param func
 * @param wait
 * @returns {Function}
 */
function throttle(func, wait,options = {}){
  var context, args,timeout,previous = 0,now;
  var throttled =  function(){
    context = this;
    args = arguments;
    //下次触发 func 剩余的时间
    now = +new Date()
    if (!previous && options.leading === false) previous = now;
    var remaining = wait - (now - previous);
    if (remaining<=0||remaining>wait){
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      previous = now;
      func.apply(context, args);
    }else if (!timeout&& options.trailing !== false) {
      timeout = setTimeout(function(){
        previous = options.leading === false ? 0 : new Date().getTime();
        timeout = null;
        func.apply(context, args)
      }, remaining);
    }
  }

  throttled.cancel = function() {
    clearTimeout(timeout);
    previous = 0;
    timeout = null;
  }

  return throttled
}
chenshuhong commented 4 years ago

动画中的防抖

function debounce(func) {
    var t;
    return function () {
        cancelAnimationFrame(t)
        t = requestAnimationFrame(func);
    }
}