美文网首页
JS(函数节流throttle)

JS(函数节流throttle)

作者: G莫_小语 | 来源:发表于2019-04-07 17:42 被阅读0次

    一、使用时间戳

    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 不能同时设置。

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

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

    相关文章

      网友评论

          本文标题:JS(函数节流throttle)

          本文链接:https://www.haomeiwen.com/subject/egjsiqtx.html