Reputation: 2020
I have the following code:
// Iterate through each of the children
for(j = 0; j < len; j++) {
var entry = sortedArray[j];
// Each entryLI is a child of nameOL <ol> element
var entryLI = document.createElement("li");
// Each entryLI should have a unique click listener
entryLI.addEventListener("click", function(event) {entry.onListItemClick()});
// Set the text of the <li> to the name of the entry
var nameNode = document.createTextNode(entry.entryName);
entryLI.appendChild(nameNode);
// Append the entry list item to the ordered list
nameOL.appendChild(entryLI);
}
I am trying to, within this loop, give each list item an event listener that handles click events. However, for some reason, clicking on any of the list items calls the event listener of the last item in the list.
Can anyone explain to me why this is?
I am coming to JavaScript from completely different languages and I am struggling with prototype-based classes.
Upvotes: 1
Views: 150
Reputation: 6404
It is because of the below line
entryLI.addEventListener("click", function(event) {entry.onListItemClick()});
is bounded to variable entry
and not to its value. So what ever is assigned or value changed throughout all loop, the value at the last iteration is holded in entry variable and every event handler function will access that variable gets the last value.
Solution: use immediate function as Kenney suggested in this Q thread or check this answer it is less ambiguous.
Upvotes: 1
Reputation: 9093
The entry
variable gets overwritten on each loop. One way to circumvent this is:
for(j = 0; j < len; j++) {
(function(entry){
....
})(sortedArray[j])
}
This IIF
(immediately-invoked-function) scopes the entry variable separately for each iteration.
Upvotes: 3