生成的事件侦听器列表仅触发最后一个

时间:2014-04-09 14:45:34

标签: javascript select for-loop onchange

以下是演示的完整代码:http://jsfiddle.net/DF2Uw/4/

基本上,我使用FOR循环生成多个事件侦听器。我生成多个<selects>并想要检测onChange事件并返回已更改的特定选择的ID。然而,似乎只有最后一个eventlistener存活,因为其他人没有触发。

对此行为的任何解释?

HTML

<ol id="slots"></ol>

JAVASCRIPT

var slotnameHtml = '';
for (var i = 0; i < 3; i += 1) {
    var slotname = document.createElement('select'),
        slottime = document.createElement('select'),
        slotlist = document.createElement('li');
    slotname.innerHTML = slotnameHtml;
    slottime.innerHTML = '<optgroup><option value="1">00:01</option><option value="2">00:02</option></optgroup>';
    slottime.id='test'+i;
    slotlist.appendChild(slotname);
    slotlist.appendChild(slottime);
    document.getElementById('slots').appendChild(slotlist);
    slottime.addEventListener('change', function () {
        alert(slottime.id)
    });;
}

2 个答案:

答案 0 :(得分:2)

那是因为绑定到change的处理程序不会立即运行,而是稍后运行。与此同时,您的for循环已经运行,slottime已经反弹到最终值(您创建的最后一个<select>元素)。所有处理程序只会看到该值。

您可以引入一个闭包,以便处理程序可以访问正确的元素:

document.getElementById("slots").appendChild(slotlist);
(function(slottime) {
    slottime.addEventListener("change", function() {
        alert(slottime.id);
    });
})(slottime);

正如Teemu在评论中所说,最简单的解决方案是利用this与处理程序内的目标元素绑定的事实:

slottime.addEventListener("change", function() {
    alert(this.id);
});

答案 1 :(得分:0)

您必须使用以下警告参数:

alert(this.getAttribute('id'));