# 节流

节流和防抖都是为了减少事件触发频率的。

# 原理

持续触发事件,每隔一定的时间就会触发一次事件. 只需要控制一下在规定的时间内不要再次出发就可以。防抖是我要控制只要在规定时间内还在触发我就清除定时器。

# 版本一(时间戳)

优点:时间时间戳来计算时间简单。

特点:会立即执行,最后一次结束之后就不会在次触发。

function throttle(func, delay) {
    var pervious = 0;
    return function () {
        var nowTime = +new Date();
        var context = this;
        var args = arguments;
        if (nowTime - pervious > delay) {
            func.apply(func, args);
            pervious = nowTime;
        }
    }
}

# 版本二(定时器)

特点:不会立即执行,最后一次结束之后还会触发一次。

function throttle(func, delay) {
    var timer;
    return function () {
        var context = this;
        var args = arguments;
        if (!timer) {
            timer = setTimeout(function () {
                func.apply(context, args);
                timer = null;
            }, delay);
        }
    }
}

# 版本三

结合前两种的优先。


function throttle(func, delay) {
    var timer, context, args, previous = 0;

    return function () {
        var now = +new Data();
        context = this;
        args = arguments;
        var restTime = delay - (now - previous);

        if (restTime < 0 || restTime > delay) {
            if (timer) {
                clearTimeout(timer);
                timer = null;
            }
            previous = now;
            func.apply(context, args);
        } else if (!timer) {
            timer = setTimeout(function () {
                timer = null;
                previous = +new Date();
                func.apply(context, args);
            }, restTime);
        }
    }
}

# 取消

function throttle(func, delay) {
    var timer, context, args, previous = 0;

    var throttle = function () {
        var now = +new Data();
        context = this;
        args = arguments;
        var restTime = delay - (now - previous);

        if (restTime < 0 || restTime > delay) {
            if (timer) {
                clearTimeout(timer);
                timer = null;
            }
            previous = now;
            func.apply(context, args);
        } else if (!timer) {
            timer = setTimeout(function () {
                timer = null;
                previous = +new Date();
                func.apply(context, args);
            }, restTime);
        }
    }

    throttle.cancel = function () {
        clearTimeout(timer);
        previous = 0;
        timer = null;
    }
    
    return throttle;