javascript之debounce函数

为一个事件绑定函数后,存在这样一个问题:当事件连续出现时,绑定函数会联系触发。但我们并不想让函数连续出发执行,只想最后一个事件出现后触发一次绑定函数。
据一个场景例子,keydown事件,当用户一直按着按键不放,绑定的函数就会不断地触发执行。用户体验差。这个时候debounce函数便派上用场。
先看一下debounce函数的原型:

debounce(function, wait, immediate)

debounce函数的大致思想是返回一个函数,在用户指定延时时间内,如果该函数被重复调用,该函数不会执行,并且重新开始延时,只到延时结束,该函数才被执行。
underscore.js和lodash.js这类知名的javascript库都提供了debounce

下面自己试着写了一下:

function debounce(func, delay) {
    var timeout;
    return function () {
        if (timeout) {
            clearTimeout(timeout);
        }
        timeout = setTimeout(function() {
            func();
        }, delay);
    }
}

var log = function() {
    console.log('haha');
}
var dlog = debounce(log, 1000);
dlog();
dlog();
dlog();
dlog(); // 只有这次调用才会输出‘haha'

下面参考[这里],写一个改进版的:

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

// Usage
var myEfficientFn = debounce(function() {
    // All the taxing stuff you do
}, 250);
window.addEventListener('resize', myEfficientFn);

你可能感兴趣的:(JavaScript)