Why is i
out of scope in the callback function
in this code?
// All menu items collection
var menuItems = document.getElementsByClassN
The variable i
is not out of scope. It's just that the event handler will be called some time after the loop has completed, so the variable i
has a value that points outside the menuItems
array.
Wrap the code in a function, to create a scope where you have a copy of the variable for each iteration:
for (var i = 0; i < menuItems.length; i++) {
// Check if element truely exsists
if (menuItems[i]) {
(function(i){
menuItems[i].addEventListener('click', function(e){
var icon = menuItems[i].children[1],
submenu = menuItems[i].children[2];
// Change icon color
if (icon.style.background !== "blue") {
icon.style.background = "blue";
} else {
icon.style.background = "red";
}
// Show/hide submenu
if (submenu.style.display !== "block") {
submenu.style.display = "block";
} else {
submenu.style.display = "none";
}
});
})(i);
}
}
As the event handler uses the i
variable, it will be captured in a closure object for that function. Each event handler will have a separate closure object, but without the function wrapper to create a separate i
variable for each iteration, all the closures would capture the same variable.
The closure for a function contains all local variables that the function uses from the outer scope. Unless menuItems
is a global variable, it will also be in the closure.