Adding addEventListener() in loop only works for last button
我从dynamodb获得了一个json数组,并在遍历它时向一个按钮添加了一个addEventListener()。 但只有最后一个按钮才能响应。
之前已经在SO上询问过这是谷歌的第一次打击所以我改变了循环以使用闭包。 但我仍然无法将addEventListener()附加到最后一个按钮以外的其他按钮。
我最初尝试过这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | for (var i = 0; i < array_length; ++i) { (function(j) { var obj = data.Items[j]; adiv.innerHTML = adiv.innerHTML +"" + obj.Event +"," + obj.Location +""; adiv.innerHTML = adiv.innerHTML +"" + obj.Date +"," + obj.Time +""; adiv.innerHTML = adiv.innerHTML +"<button id='yay_button_" + i +"' class='button-primary'>Deltag</button>"; var elem = document.getElementById('yay_button_' + j); elem.addEventListener('click', function() { alert('id: ' + j); }); })(i); } |
然后是这个较短的版本:
1 2 3 4 5 | (function(j) { document.getElementById('yay_button_' + j).addEventListener('click', function() { alert('id: ' + j); }); }(i)); |
我尝试的另一个变体是使用new创建一个按钮:
1 2 3 4 5 6 7 | function Button(id, number) { document.getElementById(id + number).addEventListener('click', function() { alert('click: ' + id + number); }); } new Button('yay_button_', i); |
我在el capitan上尝试了safari和chrome,没有错误。 当我检查它时,按钮具有正确的id,yay_button_0和_1。
主要问题是每次迭代时都会重新定义
只有在最后一次迭代时分配的事件处理程序才会以这种方式销毁。
解
一个快速的解决方案是首先循环创建所有HTML,然后执行单独的循环来分配事件处理程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // First add all the new content: var html = adiv.innerHTML; for (var i = 0; i < array_length; ++i) { var obj = data.Items[i]; html +="" + obj.Event +"," + obj.Location +""; html +="" + obj.Date +"," + obj.Time +""; html +="<button id='yay_button_" + i +"' class='button-primary'>Deltag</button>"; } adiv.innerHTML = html; // Now bind the event handlers // By using"let" instead of"var" the right value is retained // in the handlers for (let i = 0; i < array_length; ++i) { var elem = document.getElementById('yay_button_' + i); elem.addEventListener('click', function() { alert('id: ' + i); }); } |
如果您的浏览器不支持ES2015(
1 2 3 4 5 6 | for (var i = 0; i < array_length; ++i) { var elem = document.getElementById('yay_button_' + i); elem.addEventListener('click', function(i) { alert('id: ' + i); }.bind(null, i)); } |
通过trincot的善意建议我遍历阵列两次。 首先生成html然后应用addEventListener()。 第二次使用闭包来包含对addEventListener()的调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | for (var i = 0; i < array_length; ++i) { var obj = data.Items[i]; adiv.innerHTML = adiv.innerHTML +"" + obj.Event +"," + obj.Location +""; adiv.innerHTML = adiv.innerHTML +"" + obj.Date +"," + obj.Time +""; adiv.innerHTML = adiv.innerHTML +"<button id='yay_button_" + i +"' class='button-primary'>Deltag</button>"; } for (var i = 0; i < array_length; ++i) { var obj = data.Items[i]; (function(j, event) { document.getElementById('yay_button_' + j).addEventListener('click', function() { alert('id: ' + j + ', ' + event); }); }(i, obj.Event)); } |