for循环绑定事件时出现Cannot read properties of undefined错误的解决方法
问题:遍历HTML集合添加事件监听时出现
Cannot read properties of undefined错误 我写了一个for循环遍历HTML集合,给每个元素添加mouseover事件监听,但触发事件时报错,提示无法读取undefined的style属性。试过把集合元素作为参数传入事件函数,不知道怎么修复。
错误信息
main.js:5 Uncaught TypeError: Cannot read properties of undefined (reading 'style') at HTMLImageElement.<anonymous> (main.js:5:22) (anonymous) @ main.js:5
相关代码
JavaScript代码
function main(){ heads = document.getElementsByClassName("heads"); for(var i = 0; i < heads.length; i++){ heads[i].addEventListener("mouseover", function(){ heads[i].style.animation = "colorIn 2s"; heads[i].style.filter = "none"; } ) } }
HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="main.css" rel="stylesheet"> <title>player tracker</title> </head> <body id="main" onload="main()"> <h1>players online:</h1> <img src="https://mc-heads.net/avatar/Xx_DruceGamer_xX.png" class="heads" id="me" height="125px"> <img src="https://mc-heads.net/avatar/Jimbout527.png" class="heads"> <img src="https://mc-heads.net/avatar/Jimbout216.png" class="heads"> <img src="https://mc-heads.net/avatar/mrwolffff.png" class="heads"> <img src="https://mc-heads.net/avatar/MohMohMoh.png" class="heads"> <img src="https://mc-heads.net/avatar/wild_billy.png" class="heads"> <img src="https://mc-heads.net/avatar/coco_lover123.png" class="heads"> <img src="https://mc-heads.net/avatar/YAKOBISAAC5687.png" class="heads"> <script src="main.js"></script> </body> </html>
CSS代码
.heads{ height:125px; margin: 54px; filter: grayscale(); animation: none; } @keyframes colorIn{ 50% {filter:blur()} 100% {filter:none} }
修复方案
问题根源
用var声明的i是函数作用域,循环结束后i的值会等于集合的长度(比如这里是8),此时heads[i]就是undefined,事件触发时访问heads[i].style自然报错。
方法1:用this替代heads[i]
事件函数里的this指向触发事件的元素本身,直接用它操作样式即可:
function main(){ heads = document.getElementsByClassName("heads"); for(var i = 0; i < heads.length; i++){ heads[i].addEventListener("mouseover", function(){ this.style.animation = "colorIn 2s"; this.style.filter = "none"; }) } }
方法2:用let声明i
let是块级作用域,每次循环都会创建独立的i,事件函数能捕获到当前循环的i值:
function main(){ heads = document.getElementsByClassName("heads"); for(let i = 0; i < heads.length; i++){ heads[i].addEventListener("mouseover", function(){ heads[i].style.animation = "colorIn 2s"; heads[i].style.filter = "none"; }) } }
方法3:用forEach遍历集合
把HTML集合转成数组后用forEach遍历,写法更简洁:
function main(){ const heads = Array.from(document.getElementsByClassName("heads")); heads.forEach(head => { head.addEventListener("mouseover", function(){ this.style.animation = "colorIn 2s"; this.style.filter = "none"; }) }); }
内容的提问来源于stack exchange,提问作者YAKOBISAAC
相关产品推荐
相关产品推荐

