关于将多个对象绑定到点击事件here的问题有一个很好的答案,但答案仅涉及容器内的按钮。我想知道如果有一个更复杂的结构会发生什么,按钮内部的元素和容器内的非按钮元素。使用单个事件处理程序仍然会更有效吗?
考虑这个(不是那么复杂)HTML:
<div id="container">
<div class="some nice red block"></div>
<div id="button_1" class="button">
<span>some text</span>
<img src="button_1_img.jpg">
</div>
<p>some more text</p>
<img src="a_nice_pic.png">
<div id="button_2" class="button">
<span>some text</span>
<img src="button_2_img.jpg">
</div>
<div id="button_3" class="button">
<span>some text</span>
<img src="button_3_img.jpg">
<div class="some icon"></div>
</div>
<p>some more text</p>
<img src="a_nice_pic.png">
//... more text, images and let's say up to 20 buttons
</div>
我可以:
在案例1中我需要:
document.getElementById('button_1').addEventListener('click',dosomething,false);
document.getElementById('button_2').addEventListener('click',dosomething,false);
//etc... 18x
function dosomething(e){
var button=e.currentTarget.id;
//do something based on button id;
}
然后我有20个点击处理程序连接到20个不同的按钮,只有在单击按钮时才会触发。
在案例2中我需要:
document.getElementById('container').addEventListener('click',dosomething,false);
function dosomething(e){
var container=e.currentTarget;
var clicked=e.target;
while(clicked != container){
if(clicked.className == 'button'){
var button=clicked.id;
//do something based on button id;
return;
}
else{
clicked=clicked.parentNode;
}
}
}
现在我只有一个eventlistener。但它不仅会触发按钮,还会触发您在容器内单击的所有内容。并且它必须每次都向上移动以检测单击元素周围是否有按钮。
那么两者中哪一个在内存使用和性能方面效率最高? 一个有更多事件处理程序但更少做的,或只有一个事件处理程序但更复杂的代码?
我已经制作了fiddle来证明其差异。
[edit] 也许我过分简化了这个例子。有时候会有大约200多个偶数人,最多可以容纳4个容器。
答案 0 :(得分:1)
关于将多个对象绑定到点击事件here的问题有一个很好的答案,但答案仅涉及容器内的按钮。
没有。只有它的标记示例不包含其他元素,但它也适用于您的情况。
$(common parent selector).on('click', selector of target objects, function() {}); ^^^^^^^^^^^^^^^^^^^^^^^^^^
标记为$("#container").on("click", ".button", …)
。
那么两者中哪一个在内存使用和性能方面效率最高?那个有更多事件处理程序但没什么可做的,或只有一个事件处理程序但代码更复杂的那个?
都不是。正如您刚才注意到的,这是一个权衡:单个事件处理程序将占用更少的内存;点击时,多个事件处理程序可以做的事情很少。
我认为您的20个按钮没有任何问题。如果你使用数百个处理程序,内存需求只会影响性能。我建议使用更简单的解决方案 - 特别是如果您不使用为您执行复杂操作的库 - 并且只有在您遇到性能下降时才尝试事件委派。不要过早地优化。
答案 1 :(得分:0)
正如我在评论中所述,我会采取以下方式。
var buttons = document.querySelectorAll('.button');
[].forEach.call(buttons, function(button) {
button.addEventListener("click", dosomething);
});
function dosomething(e) {
var button=e.currentTarget.id;
alert (button);
}
这只会将事件监听器附加到按钮而不是像您在问题中显示的那样容器。有点时间atm,但会回来并添加更多细节:)在此期间,每个人:随时编辑并添加您宝贵的意见!