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 >
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
</div>
CodePudding user response:
use foreach instead of for loop:
images.forEach(i=> {
i.addEventListener('mouseout', function() { i.style=" transform: scale(.8)" });
i.addEventListener('mouseover', function() { i.style=" transform: scale(1.2)" });
})
CodePudding user response:
You should essentially never use var
in Javascript but use let
instead. var
has weird scoping rules and should be removed from the language, the only reason it's still there is backwards compatibility.
But you should just always use let
(or const
) and it will work as expected.
CodePudding user response:
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 >
<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 >
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
</div>
CodePudding user response:
Use arrow functions
in callback for events to have right context (this)
images = document.querySelectorAll(".gallery img");
images.forEach((img) => {
img.addEventListener("mouseout", () => {
img.style = " transform: scale(.8)";
});
img.addEventListener("mouseover", () => {
img.style = " transform: scale(1.2)";
});
});
<div >
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
<img src="https://picsum.photos/300/180">
</div>