[英]How can I make a style event with addEventListener to multiple Nodes
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]
.我正在尝试为多个图像标签设置样式事件,但我不能:错误出现在事件的匿名 function 中,当我进入一个循环以单独和为文档中的所有画廊制作效果时,
images[i]
。
Why?为什么? :
Uncaught TypeError: Cannot set property 'style' of undefined at HTMLImageElement.<anonymous>
:
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>
ES6+ solution: ES6+ 解决方案:
Simply change var
to let
in the for loop.只需将
var
更改为let
进入 for 循环。
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.如果必须使用
var
而不是let
,可以使用.bind() 为 function 设置 i 的值。 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
.否则它将引用循环中 i 的最后一个值,因为事件回调的异步性质以及由于使用
var
而导致的 i 更高的 scope。
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>
use foreach instead of for loop:使用 foreach 而不是 for 循环:
images.forEach(i=> {
i.addEventListener('mouseout', function() { i.style=" transform: scale(.8)" });
i.addEventListener('mouseover', function() { i.style=" transform: scale(1.2)" });
}) })
You should essentially never use var
in Javascript but use let
instead.您基本上不应该在 Javascript 中使用
var
,而是使用let
。 var
has weird scoping rules and should be removed from the language, the only reason it's still there is backwards compatibility. var
有奇怪的范围规则,应该从语言中删除,它仍然存在的唯一原因是向后兼容性。
But you should just always use let
(or const
) and it will work as expected.但是您应该始终使用
let
(或const
),它会按预期工作。
Use arrow functions
in callback for events to have right context (this)在回调中使用
arrow functions
使事件具有正确的上下文(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 class="gallery"> <img src="https://picsum.photos/300/180"> <img src="https://picsum.photos/300/180"> <img src="https://picsum.photos/300/180"> </div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.