循环中的 addEventListener 不适用于 IIFE
addEventListener on loop not working with IIFE
在下面的代码中,j
的值始终设置为迭代的最后一次。我已经在使用 IIFE,但它仍然给出了非预期的行为。我做错了什么吗?
function renderUsers(users) {
const frag = document.createDocumentFragment();
const userList = document.getElementById('user-list');
// Create and append all the users on the user list
for (var j = 0; j < users.length; j++) {
var item = document.createElement('li');
var division = document.createElement('div');
var userName = document.createElement('span');
var deleteButtonAnchor = document.createElement('a');
var deleteButton = document.createElement('i');
deleteButton.classList.add('material-icons');
deleteButton.textContent = 'delete_forever';
(function() {
deleteButton.addEventListener('click',function() {
console.log(j);
});
})();
deleteButtonAnchor.appendChild(deleteButton);
division.appendChild(userName);
division.appendChild(deleteButtonAnchor);
item.appendChild(division);
userName.appendChild(document.createTextNode(users[j].name.first+' '+users[j].name.last));
frag.appendChild(item);
}
userList.appendChild(frag);
}
你想用闭包做的是将迭代变量作为参数传递,这样:
(function(j) {
deleteButton.addEventListener('click',function() {
console.log(j); // j is the parameter
});
})(j);
或者正如@torazaburo 在评论中所注意到的那样,您可以对迭代变量使用 let
关键字来消除创建闭包的需要。有关 let
关键字的更多信息,您可以找到 here。但请注意,这是 ES6 功能,在旧版浏览器中未实现,因此您可能需要先转换它(例如使用 babel)。
在下面的代码中,j
的值始终设置为迭代的最后一次。我已经在使用 IIFE,但它仍然给出了非预期的行为。我做错了什么吗?
function renderUsers(users) {
const frag = document.createDocumentFragment();
const userList = document.getElementById('user-list');
// Create and append all the users on the user list
for (var j = 0; j < users.length; j++) {
var item = document.createElement('li');
var division = document.createElement('div');
var userName = document.createElement('span');
var deleteButtonAnchor = document.createElement('a');
var deleteButton = document.createElement('i');
deleteButton.classList.add('material-icons');
deleteButton.textContent = 'delete_forever';
(function() {
deleteButton.addEventListener('click',function() {
console.log(j);
});
})();
deleteButtonAnchor.appendChild(deleteButton);
division.appendChild(userName);
division.appendChild(deleteButtonAnchor);
item.appendChild(division);
userName.appendChild(document.createTextNode(users[j].name.first+' '+users[j].name.last));
frag.appendChild(item);
}
userList.appendChild(frag);
}
你想用闭包做的是将迭代变量作为参数传递,这样:
(function(j) {
deleteButton.addEventListener('click',function() {
console.log(j); // j is the parameter
});
})(j);
或者正如@torazaburo 在评论中所注意到的那样,您可以对迭代变量使用 let
关键字来消除创建闭包的需要。有关 let
关键字的更多信息,您可以找到 here。但请注意,这是 ES6 功能,在旧版浏览器中未实现,因此您可能需要先转换它(例如使用 babel)。