仅仅由于将HTML嵌套的div放在新行而不断出错

时间:2018-10-29 19:56:52

标签: javascript html

这样写HTML时不会出现错误:

<div class="game-card"><div class="flipped"></div></div>

但是如果我这样构造它,则会收到错误-无法设置未定义的属性“可见性”

<div class="game-card">
    <div class="flipped"></div>
</div>

他们不一样吗?嵌套的div仍然不是firstChild吗?

HTML

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta content="width=device-width, initial-scale=1" name="viewport">
    <link href="css/stylesheet.css" rel="stylesheet">

    <title>Memory Game</title>
  </head>
  <body>

 <div class="game-container" id="board">
        <div class="game-card">
          <div class="flipped"></div>       
        </div>
        <div class="game-card"><div class="flipped"></div></div>
        <div class="game-card"><div class="flipped"></div></div>
        <div class="game-card"><div class="flipped"></div></div> 
      </div>
  </div>
  <button onclick = "reset()">Reset</button>
  <script src="javascript/index.js"></script>
  </body>
</html>

CSS

.container {
  display: flex;
  flex-direction: column;
}

.game-container {
  display: grid;
  grid-column-gap: 10px;
  grid-row-gap: 10px;
  grid-template-columns: auto auto auto auto;
  background-color: lightblue;
  border-radius: 8px;
  padding: 10px;
  width: 90%;
  margin: 0 auto;
  max-width: 800px;
}



.game-card {
  margin: 10px auto;
  background-color: blue;
  height: 140px;
  width: 140px;
  border-radius: 10px;
  text-align: center;
  cursor: pointer;
}

.game-rules {
  display: flex;
  height: 75px;
  width: 90%;
  max-width: 800px;
  justify-content: space-between;
  align-items: center;
  margin: 0 auto;
}

.game-card-up {
  background-image: none;
  background-color: #fff;
  color: red;
  transform: scale(1.2);
}
.game-card-winner {
  background-image: none;
  background-color: #fff;
  color: red;
  border: 2px solid blue;
  animation: jiggle 1s ease-in;
}
@keyframes jiggle {
  0% {transform: skewX(5deg);}
  15% {transform: skewX(-5deg);}
  30% {transform: skewX(10deg);}
  50% {transform: skewX(-10deg);}
  75% {transform: skewX(5deg);}
  100% {transform: skewX(-5deg);}
}
.flipped {
  display: flex;
  justify-content: center;
  visibility: hidden;
  font-size: 115px;
  font-weight: bold;
  text-shadow: 2px 3px 2px #000;
}
button {
  margin: 20px auto;
  height: 30px;
  width: 120px;
  font-size: 16px;
  background-color: blue;
  color: #fff;
  border-radius: 6px;
  outline: none;
  cursor: pointer;
  display: flex;
  justify-content: center;
  box-shadow: 0 3px 0 0 rgba(0, 0, 0, 0.5);
}

JavaScript

let flippedTiles = 0;
const cards = document.getElementsByClassName("game-card");
const flippedCards = document.getElementsByClassName("game-card-up");
const winningCards = document.getElementsByClassName("game-card-winner");
const symbols = document.getElementsByClassName("flipped");
const board = document.getElementById("board");

const deck = ["Հ", "Հ", "Ղ", "Ղ", "Ճ", "Ճ", "Վ", "Վ", "Ֆ", "Ֆ", "Մ", "Մ", "Պ", "Պ", "Չ", "Չ"];
const colors = {
  Հ : "red",
  Ղ : "blue",
  Ճ : "green",
  Վ : "purple",
  Ֆ : "orange",
  Մ : "teal",
  Պ : "black",
  Չ : "pink"
};


function reset() {
  //remove winning card class for all cards / display orignal cards
  for(let i=0; i<cards.length; i++){
    cards[i].style.display = "block"
    cards[i].classList.remove("game-card-winner")
    cards[i].classList.remove("game-card-up")
    symbols[i].style.display = "flex"
    symbols[i].style.visibility = "hidden"
  }

  //reset flipped card count
  flippedTiles = 0;
  //shuffle cards
  shuffle() 
}

function shuffle(){
  //shuffle deck
  deck.sort(function() {return 0.5 - Math.random()});
  for(let i=0; i<cards.length; i++){
    //if the deck's symbol is in colors, style the symbol with that color
      for(let letter in colors){
        if(letter === deck[i]){
          symbols[i].style.color = colors[deck[i]]
        }
      }
      symbols[i].innerHTML = deck[i];
    }
}


function flip(e){
  if (flippedTiles < 2) {
    //if card clicked is down
    if (e.target.classList.contains("game-card")) {


      //flip card up
      e.target.classList.add("game-card-up");

      //show card value
      e.target.firstChild.style.visibility = "visible";
      flippedTiles++
    }
  }
  //when 2 cards have been flipped check if they match
  if(flippedTiles === 2){
    isMatch(e)
    if(winningCards.length === deck.length){
      winner()
    }
    }
  }


function isMatch(e){
  //check both cards have game-card-up class
    if(e.target.classList.contains("game-card-up")) {
      let flippedOne = flippedCards[0]
      let flippedTwo = flippedCards[1]
      //check if cards symbols match
      if(flippedOne.innerHTML === flippedTwo.innerHTML){
        flippedOne.classList.remove("game-card-up");
        flippedOne.classList.add("game-card-winner");
        flippedTwo.classList.remove("game-card-up");
        flippedTwo.classList.add("game-card-winner");

        //set flipped back to 0 so player can flip again
        flippedTiles = 0;
        console.log('a match');

      } else {
        console.log('try again');
        //set delay to prevent card flipping too soon
        setTimeout(function() {
          flippedTiles = 0;
        }, 1000)
        //set delay on flipped card to 1s before it is flipped back down
        setTimeout( function() {
          flippedOne.classList.remove("game-card-up");
          flippedOne.firstChild.style.visibility = "hidden"
          flippedTwo.classList.remove("game-card-up");
          flippedTwo.firstChild.style.visibility = "hidden"
        }, 1000)

      }   
  }
}


board.addEventListener('click', flip);

shuffle();

3 个答案:

答案 0 :(得分:1)

尝试使用firstElementChild()代替firstChild()。这似乎对我有用。当div以嵌套格式显示时,似乎firstChild并不能保证。

let flippedTiles = 0;
const cards = document.getElementsByClassName("game-card");
const flippedCards = document.getElementsByClassName("game-card-up");
const winningCards = document.getElementsByClassName("game-card-winner");
const symbols = document.getElementsByClassName("flipped");
const board = document.getElementById("board");

const deck = ["Հ", "Հ", "Ղ", "Ղ", "Ճ", "Ճ", "Վ", "Վ", "Ֆ", "Ֆ", "Մ", "Մ", "Պ", "Պ", "Չ", "Չ"];
const colors = {
  Հ : "red",
  Ղ : "blue",
  Ճ : "green",
  Վ : "purple",
  Ֆ : "orange",
  Մ : "teal",
  Պ : "black",
  Չ : "pink"
};


function reset() {
  //remove winning card class for all cards / display orignal cards
  for(let i=0; i<cards.length; i++){
    cards[i].style.display = "block"
    cards[i].classList.remove("game-card-winner")
    cards[i].classList.remove("game-card-up")
    symbols[i].style.display = "flex"
    symbols[i].style.visibility = "hidden"
  }

  //reset flipped card count
  flippedTiles = 0;
  //shuffle cards
  shuffle()
}

function shuffle(){
  //shuffle deck
  deck.sort(function() {return 0.5 - Math.random()});
  for(let i=0; i<cards.length; i++){
    //if the deck's symbol is in colors, style the symbol with that color
      for(let letter in colors){
        if(letter === deck[i]){
          symbols[i].style.color = colors[deck[i]]
        }
      }
      symbols[i].innerHTML = deck[i];
    }
}


function flip(e){
  if (flippedTiles < 2) {
    //if card clicked is down
    if (e.target.classList.contains("game-card")) {


      //flip card up
      e.target.classList.add("game-card-up");

      //show card value
      e.target.firstElementChild.style.visibility = "visible";
      flippedTiles++
    }
  }
  //when 2 cards have been flipped check if they match
  if(flippedTiles === 2){
    isMatch(e)
    if(winningCards.length === deck.length){
      winner()
    }
    }
  }


function isMatch(e){
  //check both cards have game-card-up class
    if(e.target.classList.contains("game-card-up")) {
      let flippedOne = flippedCards[0]
      let flippedTwo = flippedCards[1]
      //check if cards symbols match
      if(flippedOne.innerHTML === flippedTwo.innerHTML){
        flippedOne.classList.remove("game-card-up");
        flippedOne.classList.add("game-card-winner");
        flippedTwo.classList.remove("game-card-up");
        flippedTwo.classList.add("game-card-winner");

        //set flipped back to 0 so player can flip again
        flippedTiles = 0;
        console.log('a match');

      } else {
        console.log('try again');
        //set delay to prevent card flipping too soon
        setTimeout(function() {
          flippedTiles = 0;
        }, 1000)
        //set delay on flipped card to 1s before it is flipped back down
        setTimeout( function() {
          flippedOne.classList.remove("game-card-up");
          flippedOne.firstElementChild.style.visibility = "hidden"
          flippedTwo.classList.remove("game-card-up");
          flippedTwo.firstElementChild.style.visibility = "hidden"
        }, 1000)

      }
  }
}


board.addEventListener('click', flip);

shuffle();

答案 1 :(得分:0)

在我看来,您的代码块中可能包含一个额外的div元素:

<div class="game-container" id="board">
    <div class="game-card">
      <div class="flipped"></div>       
    </div>

    <div class="game-card"><div class="flipped"></div></div>
    <div class="game-card"><div class="flipped"></div></div>
    <div class="game-card"><div class="flipped"></div></div>

  </div></div>

应该是:

<div class="game-container" id="board">
    <div class="game-card">
      <div class="flipped"></div>       
    </div>

    <div class="game-card"><div class="flipped"></div></div>
    <div class="game-card"><div class="flipped"></div></div>
    <div class="game-card"><div class="flipped"></div></div>

 </div>

答案 2 :(得分:0)

您还有一个额外的</div>标签。我将重新格式化您的div标签,以便您可以看到它。打开和关闭div标签是垂直对齐的。

    <div class="game-container" id="board">
          <div class="game-card">
              <div class="flipped">
              </div>       
          </div>
          <div class="game-card">
              <div class="flipped">
              </div>
          </div>
          <div class="game-card">
              <div class="flipped">
              </div>
          </div>
          <div class="game-card">
              <div class="flipped">
              </div>
          </div> 
    </div>
</div>