繁体   English   中英

未捕获的类型错误:无法读取未定义的属性“样式” - 未定义的值,但我不知道为什么

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM