让我们使用scroll
侦听器示例。
如果我们有太多元素(例如20个),那些元素需要在某个滚动参数上做某事。
window.addEventListener('scroll', function(e) {
// condition 1 -> if true doSomething()
// condition 2 -> if true doSomething2()
// condition 3 -> if true doSomething3()
//...etc
});
我们将有一个超过20个条件的听众。这样好吗? 或者最好有不同的滚动事件监听器。
window.addEventListener('scroll', function(e) {
// condition 1 -> if true doSomething()
});
window.addEventListener('scroll', function(e) {
// condition 2 -> if true doSomething2()
});
window.addEventListener('scroll', function(e) {
// condition 3 -> if true doSomething3()
}); // ...etc
我不确定这将如何在幕后编辑,哪一个是更好的方法。
答案 0 :(得分:2)
第一个更好,因为它只是一个功能。在第二种格式中,需要调用所有20个滚动处理程序,即使其中只有一个实际匹配的if
语句也是如此。此外,已知滚动事件是密集的,因为它可以激活很多。
但是可以毫不费力地改进单一功能。您可以使用对象映射来代替具有20个分支(对于20个元素)的大量if
语句,而不是像这样:
window.addEventListener('scroll', function(e) {
const handlers = {
elementId1: function() {
// handle element 1
},
element2Id: function() {
// handle element 2
},
etc...
};
handlers[e.target.id]();
});
在这种情况下,您只需确保相关DOM元素具有正确的id
属性。这避免了条件逻辑。关键不在于这个特定的代码是最好的,只是有办法避免大if
个语句。
答案 1 :(得分:1)
由于danwellman的反应表明scroll
事件将被发射数次/毫秒。这可能会导致资源,内存分配等方面的开销。所以我建议您使用节流功能:
/*
* Returns a function, that, when invoked, will only be triggered at most once
* during a given window of time. Normally, the throttled function will run
* as much as it can, without ever going more than once per `wait` duration;
* but if you'd like to disable the execution on the leading edge, pass
* `{leading: false}`. To disable execution on the trailing edge, ditto.
*/
var throttle = function(func, wait, options) {
var context, args, result;
var timeout = null;
var previous = 0;
if (!options) options = {};
var later = function() {
previous = options.leading === false ? 0 : Date.now();
timeout = null;
result = func.apply(context, args);
if (!timeout) context = args = null;
};
return function() {
var now = Date.now();
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;
result = func.apply(context, args);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
};
}
现在添加普通滚动事件:
window.addEventListener('scroll', function(e) {
console.log("scroll event")
});
和受限制的只是为了比较:
window.onscroll= throttle( function(e) { console.log("throttled scroll event") }, 1000 * 5, {leading:false})
这将被发射不少于每5秒,所以在控制台中你会看到它们之间的差异:
(126) scroll event
throttled scroll event
(15) scroll event
throttled scroll event