未捕获的类型错误:无法在 runGame (logic.js:63) 和 HTMLButtonElement.start (logic.js:47) 处设置 null 的属性“innerHTML”

时间:2021-03-16 15:26:52

标签: javascript html dom events

我正在尝试使用 JS/HTML/CSS 重新创建纸牌游戏战争。我正在尝试开始物理构建我的玩家卡,但我一直遇到这个错误:Uncaught TypeError: Cannot set property 'innerHTML' of null @runGame(logic.js:63) and at HTMLButtonElement.start(logic.js.47 )。它一直突出显示 playerCard.innerHTML = displayCard(player,0);有谁知道我的问题是什么?

let userScore = document.querySelector('.score span')
userScore.innerText = 26;
let score = 26;


let cpuScore = document.querySelector('.cpuScore span')
cpuScore.innerText = 26;
let compScore = 26;


const suits = ['spades', 'diamonds', 'clubs', 'hearts'];
const cardValue = ['2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14'];


let player = [];
let computer = [];


let startGame = true;
let endGame = false;

separateCards = [
  [],
  []
]

let playerCard = document.querySelector("#user cardSpot");
let computerCard = document.querySelector("#cpu cpuHand");

let deck = []

function start() { // function that begins game. 
  if (startGame) {
    startGame = false;
    shuffleCards(deck)
    splitCards(deck)
    document.getElementById('start').style.visibility = 'hidden'

  }



  runGame()



}


document.getElementById('start').addEventListener('click', start)



function runGame() { //compares the user's card to computer's card
  if (!endGame) {
    player = separateCards[0].shift()
    computer = separateCards[1].shift()
    let totalCards = [player, computer]
    playerCard.innerHTML = displayCard(player, 0);
    computerCard.innerHTML = displayCard(computer, 0);
    war(player, computer, totalCards)
    userScore.innerHTML = separateCards[0].length
    cpuScore.innerHTML = separateCards[1].length;

    //    console.log('player is : ',player)
    //    console.log('computer is: ',computer)
    console.log(separateCards)
  } else {
    document.getElementById('warButton').style.visibility = 'hidden'
    document.querySelector('#warButton span').innerText = 'GAME OVER'
    document.getElementById('start').style.visibility = 'visible'


  }

}

function displayCard(c, p) {
  let move = p * 40;
  console.log(c, move);
}

function war(player, computer, totalCards) {

  if ((separateCards[0].length === 52) || (separateCards[1].length === 52)) {
    endGame = true;
    return;
  }
  if (player.value > computer.value) {
    separateCards[0] = separateCards[0].concat(totalCards)



  } else if (player.value < computer.value) {

    separateCards[1] = separateCards[1].concat(totalCards)
  } else if (player.value === computer.value) {
    fight(totalCards)

  }

}

function fight(totalCards) {

  if ((separateCards[0].length === 52) || (separateCards[1].length === 52)) {
    endGame = true;
    return

  } else {

    for (i = 0; i < 4; i++) {
      player = separateCards[0].shift();
      totalCards = totalCards.concat(player)
    }

    for (i = 0; i < 4; i++) {
      computer = separateCards[1].shift();
      totalCards = totalCards.concat(computer)
    }
    war(player, computer, totalCards)
  }
}

document.getElementById('warButton').addEventListener('click', start) //event listener for war button 

function createDeck(suits, cardValue) { //function for creating cards 

  for (i = 0; i < suits.length; i++) {
    for (j = 0; j < cardValue.length; j++) {
      let card = {
        value: parseInt(cardValue[j]),
        suit: suits[i]
      }
      deck.push(card)

    }

  }

}
createDeck(suits, cardValue)

function shuffleCards(deck) { //function for shuffling cards 
  for (let i = 0; i < deck.length; i++) {
    let index1 = Math.floor((Math.random() * deck.length)); //random number used as index to find a random value within the deck
    let index2 = Math.floor((Math.random() * deck.length));
    let tmp = deck[index1];

    deck[index1] = deck[index2];
    deck[index2] = tmp;
  }

}

function splitCards(deck) {
  for (i = 0; i < deck.length; i++) {
    separateCards[i % 2].push((deck[i]))
  }
}
<header>
  <h1 id="title">Let's Play War!</h1>
  <h3 id="userTitle">User:<span></span></h3>
</header>

<div id='user' class='player'></div>
<div class='score'>Score: <span></span></p>
  <div class='cardSpot'></div>


  <section id="buttons">
    <button id="warButton" class="button">WAR!<span></span></button>
    <button id="start" class="button" ;>Start</button>




    <h3 id="cpuTitle">CPU: <span></span></h3>
  </section>
</div>
</header>

<div id='cpu' class='player'>
  <div class="cpuScore">Score: <span></span></p>
    <div class="cpuHand"></div>

1 个答案:

答案 0 :(得分:0)

问题

  1. 在您的代码中, playerCard 被分配为 null,因为 #user 中没有 .cardSpot。 .cardSpot 在 #user 之外
  2. displayCard 没有返回值,所以会导致另一个错误
  3. 您的 's 以

    's 关闭,当您开始引用没有正确关闭的元素时,可能会导致一些错误

let userScore = document.querySelector('.score span')
userScore.innerText = 26;
let score = 26;


let cpuScore = document.querySelector('.cpuScore span')
cpuScore.innerText = 26;
let compScore = 26;


const suits = ['spades', 'diamonds', 'clubs', 'hearts'];
const cardValue = ['2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14'];


let player = [];
let computer = [];


let startGame = true;
let endGame = false;

separateCards = [
  [],
  []
]

const playerCard = document.querySelector("#user .cardSpot")
const computerCard = document.querySelector(".cpuHand")
//console.log(playerCard)

let deck = []

function start() { // function that begins game. 
  if (startGame) {
    startGame = false;
    shuffleCards(deck)
    splitCards(deck)
    document.getElementById('start').style.visibility = 'hidden'

  }



  runGame()



}


document.getElementById('start').addEventListener('click', start)



function runGame() { //compares the user's card to computer's card
  if (!endGame) {
    player = separateCards[0].shift()
    computer = separateCards[1].shift()
    let totalCards = [player, computer]
    playerCard.innerHTML = displayCard(player, 0);
    computerCard.innerHTML = displayCard(computer, 0);
    war(player, computer, totalCards)
    userScore.innerHTML = separateCards[0].length
    cpuScore.innerHTML = separateCards[1].length;

    //    console.log('player is : ',player)
    //    console.log('computer is: ',computer)
    //console.log(separateCards)
  } else {
    document.getElementById('warButton').style.visibility = 'hidden'
    document.querySelector('#warButton span').innerText = 'GAME OVER'
    document.getElementById('start').style.visibility = 'visible'


  }

}

function displayCard(c, p) {
  let move = p * 40;
  let suit = ' style=color:black>♠';
  switch (c.suit) {
    case 'spades':
      suit = ' style=color:black>♠';
      break;
    case 'diamonds':
      suit = ' style=color:red>♦';
      break;
    case 'hearts':
      suit = ' style=color:red>♥';
      break;
    case 'clubs':
      suit = ' style=color:black>♣';
      break;
  }
  return `<span>${c.value}</span><span${suit}</span><span>${c.value}</span>` // this is what's missing
} // must have a return value

function war(player, computer, totalCards) {

  if ((separateCards[0].length === 52) || (separateCards[1].length === 52)) {
    endGame = true;
  }
  if (player.value > computer.value) {
    separateCards[0] = separateCards[0].concat(totalCards)
  } else if (player.value < computer.value) {
    separateCards[1] = separateCards[1].concat(totalCards)
  } else if (player.value === computer.value) {
    fight(totalCards)
  }
}

function fight(totalCards) {

  if ((separateCards[0].length === 52) || (separateCards[1].length === 52)) {
    endGame = true;
    return

  } else {

    for (i = 0; i < 4; i++) {
      player = separateCards[0].shift();
      totalCards = totalCards.concat(player)
    }

    for (i = 0; i < 4; i++) {
      computer = separateCards[1].shift();
      totalCards = totalCards.concat(computer)
    }
    war(player, computer, totalCards)
  }
}

document.getElementById('warButton').addEventListener('click', start) //event listener for war button 

function createDeck(suits, cardValue) { //function for creating cards 

  for (i = 0; i < suits.length; i++) {
    for (j = 0; j < cardValue.length; j++) {
      let card = {
        value: parseInt(cardValue[j]),
        suit: suits[i]
      }
      deck.push(card)

    }

  }

}
createDeck(suits, cardValue)

function shuffleCards(deck) { //function for shuffling cards 
  for (let i = 0; i < deck.length; i++) {
    let index1 = Math.floor((Math.random() * deck.length)); //random number used as index to find a random value within the deck
    let index2 = Math.floor((Math.random() * deck.length));
    let tmp = deck[index1];

    deck[index1] = deck[index2];
    deck[index2] = tmp;
  }

}

function splitCards(deck) {
  for (i = 0; i < deck.length; i++) {
    separateCards[i % 2].push((deck[i]))
  }
}
:is(.cardSpot, .cpuHand) {
  display: grid;
  box-sizing:border-box;
  grid-template-rows: 1fr 2fr 1fr;
  height: 5rem;
  width: 4rem;
  border: 1px solid #000;
  padding: 2px;
}

:is(.cardSpot, .cpuHand) span:nth-child(1) {
  justify-self: start;
}

:is(.cardSpot, .cpuHand) span:nth-child(2) {
  justify-self: center;
  font-size: 2rem
}

:is(.cardSpot, .cpuHand) span:nth-child(3) {
  justify-self: end;
}
<header>
  <h1 id="title">Let's Play War!</h1>
  <h3 id="userTitle">User:<span></span></h3>
</header>

<!--
playerCard = document.querySelector("#user .cardSpot") returns null because .cardspot is outside #user
<div id='user' class='player'></div>
<div class='score'>Score: <span></span> // your tags are also open, they don't have closing tags
<div class='cardSpot'></div>
-->
<div id='user' class='player'>
  <div class='score'>Score: <span></span></div>
  <div class='cardSpot'></div>
</div>


<br><br>
<section id="buttons">
  <button id="warButton" class="button">WAR!<span></span></button>
  <button id="start" class="button" ;>Start</button>




  <h3 id="cpuTitle">CPU: <span></span></h3>
</section>
</div>
</header>

<div id='cpu' class='player'>
  <div class="cpuScore">Score: <span></span></div>
  <div class="cpuHand"></div>
</div>