我从dynamodb获取了一个json数组,并在遍历它时向一个按钮添加了一个addEventListener()。但只有最后一个按钮才能响应。
在SO上已经asked before,这是谷歌的第一次点击所以我改变了循环以使用闭包。但我仍然无法将addEventListener()附加到最后一个按钮以外的其他位置。
我最初尝试过这个:
for (var i = 0; i < array_length; ++i) {
(function(j) {
var obj = data.Items[j];
adiv.innerHTML = adiv.innerHTML + "<div class='row'><div class='center-div six columns'>" + obj.Event + ", " + obj.Location + "</div></div>";
adiv.innerHTML = adiv.innerHTML + "<div class='row'><div class='center-div six columns'>" + obj.Date + ", " + obj.Time + "</div></div>";
adiv.innerHTML = adiv.innerHTML + "<div class='row'><div class='center-div six columns'><button id='yay_button_" + i + "' class='button-primary'>Deltag</button></div></div>";
var elem = document.getElementById('yay_button_' + j);
elem.addEventListener('click', function() {
alert('id: ' + j);
});
})(i);
}
然后是这个较短的版本:
(function(j) {
document.getElementById('yay_button_' + j).addEventListener('click', function() {
alert('id: ' + j);
});
}(i));
我试过的另一个variant是使用new创建一个按钮:
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。
答案 0 :(得分:3)
主要问题是每次迭代时都会重新定义adiv
的HTML 。这意味着您已经绑定到adiv
的子元素的任何事件处理程序在您执行adviv.innerHTML = ...
时都会丢失。虽然您分配了相同的HTML加上一些新的HTML,但您不能分配先前定义的事件处理程序。所以他们迷路了。
只有在最后一次迭代时分配的事件处理程序才会以这种方式销毁。
快速解决方案是首先循环创建所有HTML,然后执行单独的循环来分配事件处理程序:
// First add all the new content:
var html = adiv.innerHTML;
for (var i = 0; i < array_length; ++i) {
var obj = data.Items[i];
html += "<div class='row'><div class='center-div six columns'>" + obj.Event + ", " + obj.Location + "</div></div>";
html += "<div class='row'><div class='center-div six columns'>" + obj.Date + ", " + obj.Time + "</div></div>";
html += "<div class='row'><div class='center-div six columns'><button id='yay_button_" + i + "' class='button-primary'>Deltag</button></div></div>";
}
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(适用于let
),那么您可以使用bind
:
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));
}
答案 1 :(得分:0)
来自trincot的善意建议我遍历阵列两次。首先生成html然后应用addEventListener()。第二次使用闭包来包含对addEventListener()的调用。
for (var i = 0; i < array_length; ++i) {
var obj = data.Items[i];
adiv.innerHTML = adiv.innerHTML + "<div class='row'><div class='center-div six columns'>" + obj.Event + ", " + obj.Location + "</div></div>";
adiv.innerHTML = adiv.innerHTML + "<div class='row'><div class='center-div six columns'>" + obj.Date + ", " + obj.Time + "</div></div>";
adiv.innerHTML = adiv.innerHTML + "<div class='row'><div class='center-div six columns'><button id='yay_button_" + i + "' class='button-primary'>Deltag</button></div></div>";
}
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));
}