【问题标题】:Vanilla JavaScript Flip Card game not workingVanilla JavaScript Flip Card 游戏不工作
【发布时间】:2021-02-25 08:42:29
【问题描述】:

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

“未捕获的类型错误:无法在 HTMLDivElement.flipCard 的 checkForMatch 处读取 null 的属性‘数据集’”

我该如何解决这个问题?

// * 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>

【问题讨论】:

  • 您可以使用浏览器工具调试器并在播放时使用它来跟踪变量的状态吗?看来lockBoard似乎并没有阻止第三张卡片被点击,并且卡片不会翻转
  • 当你resetBoard() 时你做了firstCard null,所以当你flipCard(). 时这是个问题

标签: javascript html css


【解决方案1】:

取消翻转卡片或禁用卡片后,您忘记将 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>

【讨论】:

    【解决方案2】:

    棋盘游戏在 onclick 事件后被重置,它调用这个resetBoard() 函数并将firstCard 变量设置为null。在下一个事件期间,变量是null

    删除这一行

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 2019-09-24
      相关资源
      最近更新 更多