js 函数防抖与节流

134 阅读1分钟

只要是用于一些不停出发的事件,比如输入框input,元素scroll等,为了节省资源,提高性能。 函数防抖(debounce): 当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。 防抖debounce代码:

function debounce(fn, wait) {
    var timeout = null;
    return function() {
        if(timeout !== null) clearTimeout(timeout);
        timeout = setTimeout(fn, wait);
    }
}
// 处理函数
function handle() {
    console.log('执行'); 
}
// 滚动事件
window.addEventListener('scroll', debounce(handle, 1000));

函数节流(throttle):当持续触发事件时,保证一定时间段内只调用一次事件处理函数。 函数节流主要有两种实现方法:时间戳和定时器。接下来分别用两种方法实现throttle~ 节流throttle代码(时间戳):

  var throttle = function (func, delay) {
    var prev = Date.now();
    return function () {
      var now = Date.now();
      if (now - prev >= delay) {
        func.apply(this, arguments);
        prev = Date.now();
      }
    }
  }
    function handle() {
      console.log('执行'); 
    }
    window.addEventListener('scroll', throttle(handle, 1000));

节流throttle代码(定时器):

var throttle = function(func, delay) {
    var timer = null;
    return function() {
        if (!timer) {
            timer = setTimeout(function() {
            func.apply(this, arguments);
                timer = null;
            }, delay);
        }
    }
}
function handle() {
    console.log('执行'); 
}
window.addEventListener('scroll', throttle(handle, 1000));

节流中用时间戳或定时器都是可以的。更精确地,可以用时间戳+定时器,当第一次触发事件时马上执行事件处理函数,最后一次触发事件后也还会执行一次事件处理函数。

节流throttle代码(时间戳+定时器):

var throttle = function(func, delay) {
    var timer = null;
    var startTime = Date.now();
    return function() {
        var curTime = Date.now();
        var remaining = delay - (curTime - startTime);
        clearTimeout(timer);
        if (remaining <= 0) {
            func.apply(arguments);
            startTime = Date.now();
        } else {
            timer = setTimeout(func, remaining);
        }
    }
}
function handle() {
    console.log('执行');
}
window.addEventListener('scroll', throttle(handle, 1000));