[英]Best practice for attaching handlers (with different actions) to multiple generated elements?
Say I'm dynamically generating some controls (example using jQuery):假设我正在动态生成一些控件(例如使用 jQuery):
for (var c=0 ; c<100 ; c++) {
$(body).append('<input id="btn_'+c+'" type="button" value="Button #'+c+'" />');
}
And I want them to have different action depending on which one is clicked (mouseover, etc), what is the best practice for attaching a handler so it knows which button is being clicked?我希望他们根据点击的那个(鼠标悬停等)有不同的动作,附加处理程序的最佳实践是什么,以便知道正在点击哪个按钮? I can think of 3 alternatives:我可以想到 3 个替代方案:
Which method is preferred or is there another alternative?哪种方法是首选或有另一种选择?
Edit:编辑:
Sorry, but I should probably mention that the number of generated elements are variable and the handler only needs the button number (ie not a completely different handler function for each button).对不起,但我可能应该提到生成元素的数量是可变的,处理程序只需要按钮编号(即每个按钮不是完全不同的处理程序函数)。 A simple example use case would be a list grabbed via ajax that you want the user to order, in this case the handler would just need the index number for the list.一个简单的示例用例是通过 ajax 抓取的列表,您希望用户订购它,在这种情况下,处理程序只需要列表的索引号。
For fixed number of elements with distinct handlers David's answer makes sense.对于具有不同处理程序的固定数量的元素,大卫的回答是有道理的。
I would say event delegation is preferred in this case:在这种情况下,我会说事件委托是首选:
$('body').on('click', 'input', function(e) {
// do something with this (the element that was clicked)
console.log(this.value);
});
This way only one event listener is attached to the button's parent (the body
in this example), but you can still access the button element that was clicked in the handler.这样,只有一个事件侦听器附加到按钮的父级(本示例中的body
),但您仍然可以访问在处理程序中单击的按钮元素。
You can f.ex map actions to the buttons like this:您可以 f.ex 将动作映射到这样的按钮:
for (var c=0 ; c<100 ; c++) {
$('body').append('<input id="btn_'+c+'" type="button" value="Button #'+c+'" />');
}
var actions = {
btn_0: function() {
console.log('btn 0 clicked');
},
btn_1: function() {
console.log('btn 1 clicked');
}
// etc...
};
$('body').on('click', 'input', function(e) {
$.isFunction(actions[this.id]) && actions[this.id].call(this);
});
Method 1 is most flexible.方法一是最灵活的。 "event delegation" mentioned by David is also just a variation of your method 1 (if you turn the Object key into a function param). David 提到的“事件委托”也只是您的方法 1 的变体(如果您将 Object 键转换为函数参数)。 When used together with other event assignment, you can flexibly turn on / off different handling over the same object.当与其他事件赋值一起使用时,您可以灵活地打开/关闭对同一对象的不同处理。 You can also handle "event propagation" better.您还可以更好地处理“事件传播”。
Method 2 is simple but it has limited capability and is a bit odd when used together with other methods to register event handler such as jQuery.方法 2 很简单,但功能有限,与其他方法一起使用时有点奇怪,以注册事件处理程序,例如 jQuery。 A nice article to read about inline handler: https://www.htmlgoodies.com/html5/javascript/working-with-inline-event-handlers.html一篇关于内联处理程序的好文章: https : //www.htmlgoodies.com/html5/javascript/working-with-inline-event-handlers.html
Method 3 sounds bad in performance as the function has to be complied many times, and will make your code harder to maintain.方法 3 的性能听起来很糟糕,因为该函数必须多次编译,并且会使您的代码更难维护。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.