I am trying to set a style event for a multiple images tags and I can’t: the error is in the anonymous function of the event when I put into a loop to make the effect individually and for all galleries in the document with images[i].
Why ? : Uncaught TypeError: Cannot set property 'style' of undefined at HTMLImageElement.<anonymous>
images = document.querySelectorAll(".gallery img");
for (var i=0; i<images.length; i++){
images[i].addEventListener('mouseout', function(){ images[i].style=" transform: scale(.8)" });
images[i].addEventListener('mouseover', function(){ images[i].style=" transform: scale(1.2)" });
} <div class="gallery">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
</div>Advertisement
Answer
ES6+ solution:
Simply change var to let in the for loop.
images = document.querySelectorAll(".gallery img");
for (let i = 0; i < images.length; i++){
images[i].addEventListener('mouseout', function(){ images[i].style=" transform: scale(.8)" });
images[i].addEventListener('mouseover', function(){ images[i].style=" transform: scale(1.2)" });
} <div class="gallery">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
</div>If you must use var rather than let, you can use .bind() to set the value of i for the function. Otherwise it will reference the last value of i in the loop because of the async nature of the event callback and the higher scope of i due to the use of var.
images = document.querySelectorAll(".gallery img");
function callback1(i){ images[i].style=" transform: scale(.8)" };
function callback2(i){images[i].style=" transform: scale(1.2)" };
for (var i=0; i<images.length; i++){
images[i].addEventListener('mouseout', callback1.bind(this, i));
images[i].addEventListener('mouseover', callback2.bind(this, i));
} <div class="gallery">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
</div>