Javascript 用Lodash节流不';行不通

Javascript 用Lodash节流不';行不通,javascript,lodash,Javascript,Lodash,我想使用Lodash的节流阀来减少scroll上的函数调用。我的代码如下: window.addEventListener('scroll', _.throttle(() => { console.log('bam'); }), 1000); window.addEventListener('scroll', _.throttle(() => { console.log('bam'); }, 1000)); 不幸的是,这不起作用-我一直在听到bam-ed,而不是每一次都听到 我能

我想使用Lodash的
节流阀
来减少scroll上的函数调用。我的代码如下:

window.addEventListener('scroll', _.throttle(() => { console.log('bam'); }), 1000);
window.addEventListener('scroll', _.throttle(() => { console.log('bam'); }, 1000));
不幸的是,这不起作用-我一直在听到
bam
-ed,而不是每一次都听到

我能做什么


CodePen:

节流功能只能生成一次,而不是每次事件触发时生成一次

var callback=..throttle(()=>{console.log('bam')},10000);
addEventListener('scroll',回调)
div{
高度:100px
}
div>div{
高度:1000px
}

您的代码中有一个错误

简单、高效、低开销的解决方案 您不需要使用lodash来实现良好的油门功能。节流功能的目的是减少浏览器资源,而不是应用太多的开销,使您使用的浏览器资源更多。此外,我对油门功能的不同使用需要许多不同的环境。这是我的列表,一个“好”的油门功能需要这个功能

  • 最小的开销
  • 立即函数调用,如果自上次调用以来间隔超过毫秒
  • 避免执行另一个间隔MS的函数
  • 延迟过多的事件触发,而不是完全删除事件
  • 在需要时更新延迟事件,使其不会变得“过时”
  • 阻止在节流功能延迟时事件的默认操作
  • 能够删除油门事件侦听器
我相信下面的油门功能满足所有这些条件

function throttle(func, alternateFunc, minimumInterval) {
    var executeImmediately = true, freshEvt = null;
    return function(Evt) {
        if (executeImmediately) { // Execute immediatly
            executeImmediately = false;
            setTimeout(function(f){ // handle further calls
                executeImmediately = true;
                if (freshEvt !== null) func( freshEvt );
                freshEvt = null;
            }, minimumInterval);
            return func( Evt );
        } else { // Delayed execute
            freshEvt = Evt;
            if (typeof alternateFunc === "function") alternateFunc( Evt );
        }
    };
}
  • 注意:
    removeEventListener
    只能删除传递给
    addEventListener
    的确切函数。如果向
    addEventListener
    发送包装函数,则
    removeEventListener
    需要此包装函数,而不是原始函数。因此,以下方法不起作用
如果您需要在
addEventListener
removeEventListener
周围使用包装器,以便它们能够正常工作,那么您可以使用以下功能

var tfCache = []; // throttled functions cache
function listen(source, eventName, func, _opts){
    var i = 0, Len = tfCache.length, cF = null, options = _opts || {};
    a: {
        for (; i < Len; i += 4)
            if (tfCache[i] === func &&
              tfCache[i+1] === (options.ALTERNATE||null) &&
              tfCache[i+2] === (options.INTERVAL||200)
            ) break a;
        cF = throttle(func, options.ALTERNATE||null, options.INTERVAL||200);
        tfCache.push(func, options.ALTERNATE||null, options.INTERVAL||200, cF);
    }
    source.addEventListener(eventName, cF || tfCache[i+3], _opts);
    return cF === null; // return whether it used the cache or not
};
function mute(source, eventName, func, _opts){
    var options = _opts || {};
    for (var i = 0, Len = tfCache.length; i < Len; i += 4)
        if (tfCache[i] === func &&
          tfCache[i+1] === (options.ALTERNATE||null) &&
          tfCache[i+2] === (options.INTERVAL||200)
        ) {
            source.removeEventListener(eventName, tfCache[i+3], options);
            return true;
        }
    return false;
}
删除滚动侦听器
Lorem ipsum dolor sit amet,是一位杰出的献身者。Morbi semper facilisis leo quis。梅塞纳斯·维塔·马莱苏阿达·尼布(Maecenas vitae malesuada nibh)。多奈克·帕特·努克在《爱欲未卜》中。维尼那提斯维塔酒店。两种不同的葡萄品种。在faucibus中,Interdum和malesuada在第一次同侧前就出名了。整数semper eget dolor et egestas。前鼻侧、后鼻侧、前庭。库拉比图尔和迪亚姆不是当时的显贵。暂时性矢状舌苔,大型调味品。前庭秃鹫毛里斯·埃吉特·米·森佩尔,埃吉特·马蒂斯·奥奇·廷西登。Phasellus坐在amet egestas turpis上。这是一个很好的例子。在我的福西布斯·奥纳雷的教堂。崔斯提克酒后驾车。佩伦茨克,奥古斯特·埃格特·特里斯蒂克·埃格斯塔斯,最重要的是欧伊斯莫·奥迪奥,这是一个非马萨之选。
纳勒姆是一只流苏图尔皮斯犬。莫里斯在尤里西斯东部。Nam faucibus,nunc eu suscipit VOLVPAT,est augue congue velit,酵母菌ornare nibh erat ac.ex.neque auctor,facilisis arcu in,molestie leo。前庭前叶、前庭前叶、前庭前叶等。塞德·韦利特·韦利特·艾利特。这是一个很好的例子。前庭是智者的前庭,是调味品的前庭。虎口浮雕和肘部浮雕同侧前庭;
前庭为精干前庭,妊娠期为流苏。在泰卢斯,我是一个空荡荡的人。塞德·特里斯蒂克,欧盟射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座射手座。这只不过是精英的生命。不要喝葡萄酒,不要喝葡萄酒,要喝葡萄酒。非交通工具。猫眼前额。欧洲精英非门户网站。Cras eleifend nisl nec车辆三色灯。整数et pellentesque urna。在欧盟的大turpis。我们的生命将永远不会毁灭。行为和侵权行为通常发生在同侧同侧。白葡萄酒、调味品和欧盟葡萄品种、优质生命元素。
克拉斯·菲利斯·泰勒斯,拍卖人非圣洁者,法雷特拉·塞德·普鲁斯。在ut调味品里苏斯中,eu ornare augue。阿利夸姆·欧古斯特。努克·廷西登、自由女神、贵族、梅托斯·波苏尔·莫里斯、欧盟伊库利斯·普鲁斯·多洛尔·非夸姆。Donec venenatis tellus ut nisi tristique,由Egesta ipsum拍卖行拍卖。整胎妊娠无胎门。多洛尼西。拉齐尼亚turpis悬钩子。伤痛前的磨牙。阿利奎姆·埃拉特·帕特。自由之门。不要因为我是菲尼布斯。这是我的门。马萨时代节杖中的梅塞纳和努拉。在同侧的位置上,坐着的是阿梅特·法雷特拉·努克·福西布斯。
多花相思,多花相思,多花相思,多花相思,多花相思,多花相思。产于蒙特斯的天然对虾和马格纳斯虎鲸(Orci varius natoque penatibus et magnis),以及印度虎鲸(nascetur ridiculus mus)。梅塞纳斯·莫利斯·瓦里乌斯·安特,非温文尔雅的前诅咒权杖。索达莱斯万岁,布兰迪特广场钻石,孕妇广场钻石,非拍卖人奥古斯·菲利斯·尤斯托。我是帕特·奈克,我是坦普尔·阿库。埃涅亚前庭位于利奥,位于奥奇赛姆佩尔的锡西顿。整型blandit Vehicleula consequat。
Donec accumsan purus quis sem dapibus aliquet。Etiam hendrerit sem eget tellus facilisis venenatis。根据康努比亚·诺斯特拉(conubia nostra)和希梅纳奥斯(inceptos himenaeos)的规定,社会责任和责任等级为:。Suspendisse vel Consequeat est。我是康瓦利斯·泰勒斯。维瓦摩斯·奎斯·森佩尔·奥迪奥。毛里斯·奎斯·因特杜姆·利古拉。在libero sollicitudin,在varius nunc dapibus的Praesent cursus ante。奥古斯·尼西(Vivamus augue nisi)、埃尼姆·乌特(enim ut)的库苏斯(cursus)、埃利芬德·亨德雷特·内克(eleifend hendrerit neque)。罗那库斯尼布
function clickFunctor(){ /*...*/ }

// This code throttles clickFunctor to 500ms
var throttledFunctor = throttle(clickFunctor, null, 500); // WORKS
addEventListener("click", throttledFunctor, false); // WORKS

// ONLY this removeEventListener works
removeEventListener("click", throttledFunctor, false); // WORKS

// For example, this removeEventListener does not work
removeEventListener("click", throttle(clickFunctor, null, 500), false); // FAILS
// This removeEventListener also does not work
removeEventListener("click", clickFunctor, false); // FAILS
var tfCache = []; // throttled functions cache
function listen(source, eventName, func, _opts){
    var i = 0, Len = tfCache.length, cF = null, options = _opts || {};
    a: {
        for (; i < Len; i += 4)
            if (tfCache[i] === func &&
              tfCache[i+1] === (options.ALTERNATE||null) &&
              tfCache[i+2] === (options.INTERVAL||200)
            ) break a;
        cF = throttle(func, options.ALTERNATE||null, options.INTERVAL||200);
        tfCache.push(func, options.ALTERNATE||null, options.INTERVAL||200, cF);
    }
    source.addEventListener(eventName, cF || tfCache[i+3], _opts);
    return cF === null; // return whether it used the cache or not
};
function mute(source, eventName, func, _opts){
    var options = _opts || {};
    for (var i = 0, Len = tfCache.length; i < Len; i += 4)
        if (tfCache[i] === func &&
          tfCache[i+1] === (options.ALTERNATE||null) &&
          tfCache[i+2] === (options.INTERVAL||200)
        ) {
            source.removeEventListener(eventName, tfCache[i+3], options);
            return true;
        }
    return false;
}