At the time the function is called the loop will have completed. There is only one i
variable and the function always sees its current value. So if you use i
from inside the function you will see it with the value lis.length
.
There are ways around it. If you can use ES2015 (possibly through a transpiler), then you can write:
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");
};
and now you have a different i
for each time round the loop.
Or in older code you can push the loop body out to another function and pass i
in as a parameter. That has the same effect of binding a different 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);
}
(which is the code automatically produced by babel from the ES2015 example I gave above)