假设我正在动态生成一些控件(例如使用jQuery):
for (var c=0 ; c<100 ; c++) {
$(body).append('<input id="btn_'+c+'" type="button" value="Button #'+c+'" />');
}
我希望他们根据点击哪一个(鼠标悬停等)有不同的动作,附加处理程序的最佳做法是什么,它知道点击了哪个按钮?我可以想到3个替代方案:
首选哪种方法还是另一种方法?
修改
很抱歉,但我应该提一下,生成的元素数量是可变的,处理程序只需要按钮编号(即每个按钮的处理函数不是完全不同)。一个简单的示例用例是通过ajax抓取的列表,您希望用户订购,在这种情况下,处理程序只需要列表的索引号。
对于具有不同处理程序的固定数量的元素,David的回答是有道理的。
答案 0 :(得分:1)
我想在这种情况下首选event delegation:
$('body').on('click', 'input', function(e) {
// do something with this (the element that was clicked)
console.log(this.value);
});
这样只有一个事件监听器附加到按钮的父级(本例中为body
),但您仍然可以访问在处理程序中单击的按钮元素。
您可以将动作映射到按钮,如下所示:
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);
});
答案 1 :(得分:0)
方法1最灵活。 David提到的“事件委托”也只是方法1的一种变体(如果将Object键转换为函数参数)。与其他事件分配一起使用时,可以灵活地打开/关闭同一对象的不同处理。您还可以更好地处理“事件传播”。
方法2很简单,但功能有限,与其他方法(例如jQuery)一起注册事件处理程序时,方法2有点奇怪。一篇不错的文章,介绍了内联处理程序:https://www.htmlgoodies.com/html5/javascript/working-with-inline-event-handlers.html
方法3听起来性能很差,因为该函数必须被多次编译,并使您的代码难以维护。