![](/img/trans.png)
[英]I don't know how to fix this error: Uncaught TypeError: Cannot read property 'classList' of undefined
[英]Uncaught TypeError: Cannot read property 'style' of undefined - Undefined values but I don't know why
所以我试图在点击卡片时翻转卡片。 我在 addEventListener 之前做了一个 console.log(card[i]),它工作正常,但是在 addEventListener 之后 console.log 上出现了错误。
我得到的错误是: Uncaught TypeError: Cannot read property 'style' of undefined
这些是我的代码
var card = document.querySelectorAll('.card'); var cardInner = document.querySelectorAll('.card-inner'); var cardBack = document.querySelectorAll('.card-back'); for (var i=0; i < card.length; i++) { console.log(card[i]); // works fine // when a card is clicked card[i].addEventListener('click', function(){ // flip THAT card console.log(card[i]); // undefined value card[i].style.perspective = "500px"; cardInner[i].style.transform = "rotateY(180deg)"; cardInner[i].style.transition = "all 0.5s"; cardBack[i].style.transform = "rotateY(180deg)"; }); }
<,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width. initial-scale=1.0"> <title>Memory Game</title> <link rel="stylesheet" href="style.css"> </head> <body> <section class="box"> <div class="card"> <div class="card-inner"> <div class="card-front"></div> <div class="card-back"></div> </div> </div> <div class="card"> <div class="card-inner"> <div class="card-front"></div> <div class="card-back"></div> </div> </div> </section> <script src="app.js"></script> </body> </html>
这里的问题是您正在创建一个闭包,并且您正在关闭错误的变量。
您正在创建的每个内部函数都将在局部变量i
上“关闭”。 这意味着这个局部变量将在循环结束后保持活动状态,并且内部函数将能够访问它。 但是,重要的是要注意内部函数可以访问变量i
,而不是创建 function 时i
的值。 直到循环完成后,点击事件侦听器才会触发,但是一旦循环完成, i
将具有值card.length
,当然card[i]
将是未定义的,因为i
指向末尾的元素你的card
阵列。
相反,您需要做的是分别“关闭” i
的每个值。 一种方法是创建另一个 function 并将i
的值传递给此 function:
function addEventListenerToCard(index) {
card.addEventListener('click', function(){
// flip THAT card
console.log(card[index]);
card.style.perspective = "500px";
cardInner[index].style.transform = "rotateY(180deg)";
cardInner[index].style.transition = "all 0.5s";
cardBack[index].style.transform = "rotateY(180deg)";
});
}
for (var i=0; i < card.length; i++) {
console.log(card[i]); // works fine
// when a card is clicked
addEventListenerToCard(i);
}
在这种情况下,对addEventListenerToCard
的每次调用都会为参数index
创建一个新的 scope ,并且此参数不会更改,因此每个事件侦听器都会跟踪它关联到哪个卡。
您也可以尝试使用Array.forEach
而不是循环:
card.forEach(function (cardElement, index) {
console.log(card[index]); // can also write "console.log(cardElement);" here
// when a card is clicked
card[index].addEventListener('click', function(){
// flip THAT card
console.log(card[index]); // should no longer be an undefined value
card[index].style.perspective = "500px";
cardInner[index].style.transform = "rotateY(180deg)";
cardInner[index].style.transition = "all 0.5s";
cardBack[index].style.transform = "rotateY(180deg)";
});
});
卢克完美地回答了另一种解决方案是在您的addEventListener
中使用event.target
var card = document.querySelectorAll('.card'); for (var i=0; i < card.length; i++) { // console.log(card[i]); // works fine // when a card is clicked card[i].addEventListener('click', function(event){ var elem=event.currentTarget; var cardInner = elem.querySelector('.card-inner'); var cardBack = elem.querySelector('.card-back'); // flip THAT card elem.style.perspective = "500px"; cardInner.style.transform = "rotateY(180deg)"; cardInner.style.transition = "all 0.5s"; cardBack.style.transform = "rotateY(180deg)"; }); }
.card{ width:100px; height:100px; background-color:red; margin:5px; }.card-inner{ width:90px; height:90px; background-color:yellow; }.card-front{ margin:5px; width:50%; height:50%; background-color:green; }.card-back{ margin:5px; width:50%; height:50%; background-color:orange; }
<,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width. initial-scale=1.0"> <title>Memory Game</title> <link rel="stylesheet" href="style.css"> </head> <body> <section class="box"> <div class="card"> <div class="card-inner"> <div class="card-front"></div> <div class="card-back"></div> </div> </div> <div class="card"> <div class="card-inner"> <div class="card-front"></div> <div class="card-back"></div> </div> </div> </section> </body> </html>
希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.