When the function is called, the loop will have already finished its execution. Inside the function, there is a single i
variable that always reflects its current value. Therefore, if you reference i
within the function, it will show as lis.length
.
There are workarounds to this issue. If you have access to ES2015 (potentially through a transpiler), you can do the following:
const lis = document.querySelectorAll('li');
for(let i = 0; i < lis.length; i++){
lis[i].addEventListener('mouseover', () => lis[i].style.color = 'green');
lis[i].addEventListener('mouseout', () => lis[i].style.color ="black");
};
This way, you create a distinct i
for each iteration of the loop.
Alternatively, in older code, you can move the loop body to another function and pass i
as a parameter. This approach achieves the same outcome of binding a unique variable for each event:
var lis = document.querySelectorAll('li');
var _loop = function _loop(i) {
lis[i].addEventListener('mouseover', function () {
return lis[i].style.color = 'green';
});
lis[i].addEventListener('mouseout', function () {
return lis[i].style.color = "black";
});
};
for (var i = 0; i < lis.length; i++) {
_loop(i);
}
(this code is automatically generated by babel from the earlier ES2015 example)