2017-01-16 61 views
0

在下面的代码中,j的值始终设置为迭代的最后一个。我已经使用了一个IIFE,但它仍然给出了预期的行为。有什么我做错了吗?addEventListener on循环不适用于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); 
} 
+1

你没有将'j'传递给IIFE。在循环中创建函数也被认为是不好的做法。改用外部功能。请参阅http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – Teemu

回答

2

你想关闭做的,是将迭代变量作为参数传递,因为这样的:

(function(j) { 
    deleteButton.addEventListener('click',function() { 
      console.log(j); // j is the parameter 
    }); 
})(j); 

或在评论@torazaburo相当注意,您可以使用关键字let用于迭代变量以消除创建闭包的需要。更多关于let的关键字你可以找到here。但请注意,这是ES6功能,这在旧版浏览器中未实现,因此您可能需要先将其传输(例如使用babel)。

+0

为什么选择downvoted? –

+0

因为根本就不需要关闭,因为整个问题都可以用'for ...'来解决。 – 2017-01-16 19:51:49

+0

当然,但问题是“我有什么做错了吗?”。回答说在提供的代码中出了什么问题 –