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>