继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

JS函数的防抖和节流(二)

慕粉4026617
关注TA
已关注
手记 3
粉丝 3
获赞 12

上篇说了节流的一部分,节流实质上是:如果你持续触发事件,每隔一段时间,只执行一次事件。

根据这个需求我们可以通过时间戳实现节流:

//第一个实现方式function throttle(func, wait) {
    var context, args;
    var previous = 0;
    return function() {
        var now = +new Date();
        context = this;
        args = arguments;
        if (now - previous > wait) {
            func.apply(context, args);
            previous = now;
        }
    }}//另外补充一下获取时间戳的方式吧// new Date().getTime()// Date.parse(new Date())// +new Date()// Date.now()// 通过判断再次点击时间与上次点击时间的时间戳是否大于传入的时间,来判断函数是否被执行

另一种实现方式通过定时器,通过判断定时器的存在来决定函数是否被执行

// 第二种实现方式function throttle(func, wait) {
    var timeout;
    var previous = 0;

    return function() {
        context = this;
        args = arguments;
        if (!timeout) {
            timeout = setTimeout(function(){
                timeout = null;
                func.apply(context, args)
            }, wait)
        }

    }}//

看上面两种实现方式的代码,比较可以发现:

  1. 方式一的事件会立刻执行,因为获取当前时间戳肯定会大于wait传入的时间,方式二事件会在 n 秒后第一次执行,因为设置了定时器,所以会在wait秒之后执行。

  2. 如果我们连续执行了几次,第一种方式会在事件结束之后不会再执行函数,第二种会在结束之后wait秒之后再执行一次。

怎么中和实现一下两种方式呢?

// 第三种方式function throttle(func, wait, options) {
    var timeout, context, args, result;
    var previous = 0;
    if (!options) options = {};

    var later = function() {
        previous = options.leading === false ? 0 : new Date().getTime();
        timeout = null;
        func.apply(context, args);
        if (!timeout) context = args = null;
    };
    var throttled = function() {
        var now = new Date().getTime();
        if (!previous && options.leading === false) previous = now;
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
        if (remaining <= 0 || remaining > wait) {
            if (timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            previous = now;
            func.apply(context, args);
            if (!timeout) context = args = null;
        } else if (!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaining);
        }
    };
    return throttled;}
//leading:false 表示禁用第一次执行
//trailing: false 表示禁用停止触发的回调
//那就是 leading:false 和 trailing: false 不能同时设置。
一般使用第一种方式就会满足我们的需求


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP