将处理程序(具有不同操作)附加到多个生成的元素的最佳实践?

时间:2013-02-20 20:12:30

标签: javascript

假设我正在动态生成一些控件(例如使用jQuery):

for (var c=0 ; c<100 ; c++) {
  $(body).append('<input id="btn_'+c+'" type="button" value="Button #'+c+'" />');
}

我希望他们根据点击哪一个(鼠标悬停等)有不同的动作,附加处理程序的最佳做法是什么,它知道点击了哪个按钮?我可以想到3个替代方案:

  1. 将相同的处理程序(通过javascript)附加到所有按钮,让处理程序解析元素ID以确定单击哪一个
  2. 在为控件生成HTML时添加内联处理程序(即onclick =“do_something('+ c +');”)
  3. 为处理程序参数
  4. 中设置了按钮编号的每个元素附加不同的处理程序(例如,使用循环)

    首选哪种方法还是另一种方法?

    修改

    很抱歉,但我应该提一下,生成的元素数量是可变的,处理程序只需要按钮编号(即每个按钮的处理函数不是完全不同)。一个简单的示例用例是通过ajax抓取的列表,您希望用户订购,在这种情况下,处理程序只需要列表的索引号。

    对于具有不同处理程序的固定数量的元素,David的回答是有道理的。

2 个答案:

答案 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听起来性能很差,因为该函数必须被多次编译,并使您的代码难以维护。