javascript - Vanilla JavaScript Flip Card 游戏无法运行

标签 javascript html css

我正在制作简单的翻转纸牌游戏,如果两张纸牌匹配,则将纸牌锁定在翻转位置,如果不匹配,则将它们切换回静止位置。当第一对牌翻转时,无论是否匹配,游戏都会正常进行。问题是当我单击第三张卡时,控制台返回错误:

"Uncaught TypeError: Cannot read property 'dataset' of null at checkForMatch at HTMLDivElement.flipCard"

我该如何解决这个问题?

// * Declaring Varaibles
// Get cards on the board
const cards = document.querySelectorAll(".card");
let isCardFlipped = false;
let lockBoard = false;
let firstCard, secondCard;

// * Functions
// Flips cards over
function flipCard() {
  if (lockBoard) return;
  if (this === firstCard) return;

  // Adding class name "flip" to all HTML elments with the class name "card"
  this.style.transform = "rotateY(180deg)";

  if (!isCardFlipped) {
    isCardFlipped = true;
    firstCard = this;

    return;
  }

  secondCard = this;
  checkForMatch();
}

// Checks to see if the cards match
function checkForMatch() {
  let isMatch = firstCard.dataset.monke === secondCard.dataset.monke;

  // isMatch ? disableCards() : unflipCards();

  if (isMatch) {
    disableCards();
  }
  else {
    unflipCards();
  }
}

// Locks the cards in place if they match
function disableCards() {
  firstCard.removeEventListener("click", flipCard);
  secondCard.removeEventListener("click", flipCard);

  resetBoard();
}

// Flips the cards back over if they don't match
function unflipCards() {
  lockBoard = true;

  setTimeout(() => {
    firstCard.style.transform = "";
    secondCard.style.transform = "";

    resetBoard();
  }, 1000);

}

// Resets the board
function resetBoard() {
  [hasFlippedCard, lockBoard] = [false, false];
  [firstCard, secondCard] = [null, null];
}

// * Event Listeners
// Event listener for all the cards
cards.forEach((item) => {
  item.addEventListener("click", flipCard);
});
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "Londrina Solid", cursive;
}

body {
    background: linear-gradient(180deg, rgb(34, 179, 34), rgb(163, 126, 57));
    height: 100vh;
}

.container {
    padding: 1rem;
    width: 100%;
    height: 100%;
}

h1 {
    text-align: center;
    margin-bottom: 2rem;
    font-size: 3rem;
    color: #000;
}

.row {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    margin: 2rem;
    padding-top: 1rem;
}

.card-container {
    position: relative;
    margin: auto;
    width: 150px;
    height: 200px;
}

.card {
    position: absolute;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    transition: transform 1s ease;
}

.front-face {
    position: absolute;
    backface-visibility: hidden;
    height: 100%;
    width: 100%;
    background: rgb(244, 238, 86);
    border-radius: 10px;
}

.back-face {
    position: absolute;
    backface-visibility: hidden;
    transform: rotateY(180deg);
}

.pic-container {
    height: 200px;
    width: 150px;
}

img {
    height: 100%;
    width: 100%;
    border-radius: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="preconnect" href="https://fonts.gstatic.com">
  <link href="https://fonts.googleapis.com/css2?family=Londrina+Solid&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="style.css">
  <title>Matching Game</title>
</head>
<body>
  <div class="container">
    <h1>Monke Matching Game</h1>
    <div class="row">
      <div class="card-container">
        <div class="card" data-monke="gorilla">
          <div class="front-face">
            <img src="img/Banna-cartoon.png" alt="">
          </div>
          <div class="back-face">
            <div class="pic-container">
              <img src="img/monke1.jpg" alt="">
            </div>
          </div>
        </div>
      </div>
      <div class="card-container">
        <div class="card" data-monke="gorilla">
          <div class="front-face">
            <img src="img/Banna-cartoon.png" alt="">
          </div>
          <div class="back-face">
            <div class="pic-container">
              <img src="img/monke1.jpg" alt="">
            </div>
          </div>
        </div>
      </div>
      <div class="card-container">
        <div class="card" data-monke="chimp">
          <div class="front-face">
            <img src="img/Banna-cartoon.png" alt="">
          </div>
          <div class="back-face">
            <div class="pic-container">
              <img src="img/monke2.jpg" alt="">
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="row">
      <div class="card-container">
        <div class="card" data-monke="chimp">
          <div class="front-face">
            <img src="img/Banna-cartoon.png" alt="">
          </div>
          <div class="back-face">
            <div class="pic-container">
              <img src="img/monke2.jpg" alt="">
            </div>
          </div>
        </div>
      </div>
      <div class="card-container">
        <div class="card" data-monke="baby">
          <div class="front-face">
            <img src="img/Banna-cartoon.png" alt="">
          </div>
          <div class="back-face">
            <div class="pic-container">
              <img src="img/monke3.jpg" alt="">
            </div>
          </div>
        </div>
      </div>
      <div class="card-container">
        <div class="card" data-monke="baby">
          <div class="front-face">
            <img src="img/Banna-cartoon.png" alt="">
          </div>
          <div class="back-face">
            <div class="pic-container">
              <img src="img/monke3.jpg" alt="">
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>


  <script src="app.js"></script>
</body>
</html>

最佳答案

在取消翻转卡片或禁用卡片后,您忘记将 isCardFlipped 设置为 false。

// * Declaring Varaibles
// Get cards on the board
const cards = document.querySelectorAll(".card");
let isCardFlipped = false;
let lockBoard = false;
let firstCard, secondCard;

// * Functions
// Flips cards over
function flipCard() {
  if (lockBoard) return;
  if (this === firstCard) return;

  // Adding class name "flip" to all HTML elments with the class name "card"
  this.style.transform = "rotateY(180deg)";

  if (!isCardFlipped) {
    isCardFlipped = true;
    firstCard = this;

    return;
  }

  secondCard = this;
  checkForMatch();
}

// Checks to see if the cards match
function checkForMatch() {
  let isMatch = firstCard.dataset.monke === secondCard.dataset.monke;
  // isMatch ? disableCards() : unflipCards();

  if (isMatch) {
    disableCards();
  }
  else {
    unflipCards();
  }
}

// Locks the cards in place if they match
function disableCards() {
  firstCard.removeEventListener("click", flipCard);
  secondCard.removeEventListener("click", flipCard);
  isCardFlipped = false;
  resetBoard();
}

// Flips the cards back over if they don't match
function unflipCards() {
  lockBoard = true;
  isCardFlipped = false;
  setTimeout(() => {
    firstCard.style.transform = "";
    secondCard.style.transform = "";

    resetBoard();
  }, 1000);

}

// Resets the board
function resetBoard() {
  [hasFlippedCard, lockBoard] = [false, false];
  [firstCard, secondCard] = [null, null];
}

// * Event Listeners
// Event listener for all the cards
cards.forEach((item) => {
  item.addEventListener("click", flipCard);
});
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "Londrina Solid", cursive;
}

body {
    background: linear-gradient(180deg, rgb(34, 179, 34), rgb(163, 126, 57));
    height: 100vh;
}

.container {
    padding: 1rem;
    width: 100%;
    height: 100%;
}

h1 {
    text-align: center;
    margin-bottom: 2rem;
    font-size: 3rem;
    color: #000;
}

.row {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    margin: 2rem;
    padding-top: 1rem;
}

.card-container {
    position: relative;
    margin: auto;
    width: 150px;
    height: 200px;
}

.card {
    position: absolute;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    transition: transform 1s ease;
}

.front-face {
    position: absolute;
    backface-visibility: hidden;
    height: 100%;
    width: 100%;
    background: rgb(244, 238, 86);
    border-radius: 10px;
}

.back-face {
    position: absolute;
    backface-visibility: hidden;
    transform: rotateY(180deg);
}

.pic-container {
    height: 200px;
    width: 150px;
}

img {
    height: 100%;
    width: 100%;
    border-radius: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="preconnect" href="https://fonts.gstatic.com">
  <link href="https://fonts.googleapis.com/css2?family=Londrina+Solid&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="style.css">
  <title>Matching Game</title>
</head>
<body>
  <div class="container">
    <h1>Monke Matching Game</h1>
    <div class="row">
      <div class="card-container">
        <div class="card" data-monke="gorilla">
          <div class="front-face">
            <img src="img/Banna-cartoon.png" alt="">
          </div>
          <div class="back-face">
            <div class="pic-container">
              <img src="img/monke1.jpg" alt="">
            </div>
          </div>
        </div>
      </div>
      <div class="card-container">
        <div class="card" data-monke="gorilla">
          <div class="front-face">
            <img src="img/Banna-cartoon.png" alt="">
          </div>
          <div class="back-face">
            <div class="pic-container">
              <img src="img/monke1.jpg" alt="">
            </div>
          </div>
        </div>
      </div>
      <div class="card-container">
        <div class="card" data-monke="chimp">
          <div class="front-face">
            <img src="img/Banna-cartoon.png" alt="">
          </div>
          <div class="back-face">
            <div class="pic-container">
              <img src="img/monke2.jpg" alt="">
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="row">
      <div class="card-container">
        <div class="card" data-monke="chimp">
          <div class="front-face">
            <img src="img/Banna-cartoon.png" alt="">
          </div>
          <div class="back-face">
            <div class="pic-container">
              <img src="img/monke2.jpg" alt="">
            </div>
          </div>
        </div>
      </div>
      <div class="card-container">
        <div class="card" data-monke="baby">
          <div class="front-face">
            <img src="img/Banna-cartoon.png" alt="">
          </div>
          <div class="back-face">
            <div class="pic-container">
              <img src="img/monke3.jpg" alt="">
            </div>
          </div>
        </div>
      </div>
      <div class="card-container">
        <div class="card" data-monke="baby">
          <div class="front-face">
            <img src="img/Banna-cartoon.png" alt="">
          </div>
          <div class="back-face">
            <div class="pic-container">
              <img src="img/monke3.jpg" alt="">
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>


  <script src="app.js"></script>
</body>
</html>

关于javascript - Vanilla JavaScript Flip Card 游戏无法运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66360532/

相关文章:

html - 向导航栏添加词缀

javascript - 文件上传不起作用,但在 Codepen 中正常

javascript - CSS:添加文本溢出属性后,绝对定位的文本不会在 div 中居中

javascript - javascript 中 <a> 的 w3c 验证

javascript - bootstrap下拉菜单不下拉?

javascript - 过滤和格式化日期数组

javascript - 全页平滑滚动

php - 在 Wordpress 的循环中显示每个帖子的类别名称

html - 为什么我的图像不会出现在下一行?

javascript - 检查传入的参数是否在数组对象中