JS(函数节流throttle)

一、使用时间戳

function throttle1(fn, wait) {
    let previous = 0;
    return function () {
        let now = new Date().getTime();
        if (now - previous > wait) {
            fn.apply(this, arguments);
            previous = now;
        }
    }
}
  • 注:当鼠标移入的时候,事件立刻执行,每过 1s 会执行一次,如果在 4.2s 停止触发,以后不会再执行事件。

二、使用定时器

function throttle(fn, wait) {
    let timer;
    return function () {
        if (!timer) {
            timer = setTimeout(() => {
                timer = null;
                fn.apply(this, arguments);
            }, wait)
        }
    }
}
  • 注:当鼠标移入的时候,事件不会立刻执行,晃了 3s 后终于执行了一次,此后每 3s 执行一次,当数字显示为 3 的时候,立刻移出鼠标,相当于大约 9.2s 的时候停止触发,但是依然会在第 12s 的时候执行一次事件。
  • 区别:
    (1) 第一种事件会立刻执行,第二种事件会在 n 秒后第一次执行
    (2) 第一种事件停止触发后没有办法再执行事件,第二种事件停止触发后依然会再执行一次事件

三、两种结合使用


function throttle(fn, wait) {
    let timer;
    let previous = 0;
    let throttled = function () {
        let now = +new Date();
        // remaining 不触发下一次函数的剩余时间
        let remaining = wait - (now - previous);
        if (remaining < 0) {
            if (timer) {
                clearTimeout(timer);
                timer = null;
            }
            previous = now;
            fn.apply(this, arguments)
        } else if (!timer) {
            timer = setTimeout(() => {
                previous = new Date().getTime();
                timer = null;
                fn.apply(this, arguments);
            }, remaining);
        }
    }
    return throttled;
}


  • 注意:这个综合了两者的优势,鼠标移入能立刻执行,停止触发的时候还能再执行一次!

四、可配置(立即执行但结束后不执行,不立即执行但结束后要执行一次)

  • leading:false 表示禁用第一次执行
  • trailing: false 表示禁用停止触发的回调
function throttle(fn, wait, options = {}) {
    let timer;
    let previous = 0;
    let throttled = function () {
        let now = +new Date();
        // remaining 不触发下一次函数的剩余时间
        if (!previous && options.leading === false) previous = now;
        let remaining = wait - (now - previous);
        if (remaining < 0) {
            if (timer) {
                clearTimeout(timer);
                timer = null;
            }
            previous = now;
            fn.apply(this, arguments)
        } else if (!timer && options.trailing !== false) {
            timer = setTimeout(() => {
                previous = options.leading === false ? 0 : new Date().getTime();
                timer = null;
                fn.apply(this, arguments);
            }, remaining);
        }
    }
    return throttled;
}

  • 注意:那就是 leading:false 和 trailing: false 不能同时设置。

  • 节流:在规定时间内,保证执行一次该函数。

  • 防抖:当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 我愿 像那执着的蚕一样 吐露内心的真诚 一圈一圈地 把自己缠绕成 一个希望 但愿你 能够把我 浸泡在你的深情中 然...
    Sarah潇潇阅读 96评论 3 2
  • 李科技 一个和粥有关的节日 五谷熬成的粥 融汇了好几种颜色 这大概就是 酸甜苦辣的色彩 还有那些鸡零狗碎 的无奈 ...
    李科技原创发布阅读 239评论 0 1
  • 问题一: 首次加载动画 由于单页面,不可避免第一次加载需要耗时, 所以需要搞个加载动画 解决:两步走, 第一步:在...
    ZZES_ZCDC阅读 366评论 0 1
  • 伴随着六月渐趋炙热的暑气,手机朋友圈也不时会泛起阵阵热浪来。 那一天,你看到了这样一则转帖: 这天气就算老公跟人家...
    龙潭独步阅读 301评论 0 0