简体   繁体   English

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

[英]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 个替代方案:

  1. Attach the same handler (via javascript) to all buttons and have the handler parse the element id to determine which one is clicked将相同的处理程序(通过 javascript)附加到所有按钮,并让处理程序解析元素 id 以确定单击了哪个
  2. Add the handlers inline when generating the HTML for the controls (ie have onclick="do_something('+c+');")在为控件生成 HTML 时内联添加处理程序(即有 onclick="do_something('+c+');")
  3. Attach different handler (eg with a loop) for each element that has the button number set in the handler argument为每个在 handler 参数中设置了按钮编号的元素附加不同的处理程序(例如使用循环)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM