0

我正在通过构建一个井字游戏应用程序来练习 html/vanilla JS。我在 board square s 中添加了一个事件监听器<div>,并使用 X 和 O 创建元素并将它们插入到 DOM 中,然后调用一个函数来检查是否有获胜者。该checkIfPlayerWins()函数进行一些检查,然后调用,alert如果玩家获胜或平局。

我遇到的问题是,如果玩家获胜,则会在将 X 或 O 插入 DOM 之前调用警报,这看起来很有趣。我不想使用 a setTimeout,因为它看起来有点 hacky。我尝试了async/awaitnew Promise从中创建了一个,但似乎无法让它工作。

好的,这里有一些代码和相关链接: insertAdjacentElement MDN docs My github/ code repo

  setEventListeners() {
    const board = document.querySelector('.board')
    const squares = board.children

    for (let i = 0; i < squares.length; i++) {
      squares[i].addEventListener('click', (event) => {
        const squareEl = event.target
        if (!squareEl.firstChild) {
          this.makeMove(squareEl)
        } else {
          alert('That square is already taken!')
        }
      })
    }
  }

  makeMove(eventTarget) {
    let playerMarker = ''
    if (this.playerOneTurn) {
      playerMarker = 'X'
    } else {
      playerMarker = 'O'
    }

    eventTarget.insertAdjacentElement('beforeend', createElementFromHTML(`<div>${playerMarker}</div>`))

    this.updateGameState(eventTarget.className, playerMarker)

    this.playerOneTurn = !this.playerOneTurn
    this.updatePlayerTurnText()
  }

export function createElementFromHTML(htmlString) {
  const template = document.createElement('template')
  template.innerHTML = htmlString.trim()
  return template.content.firstChild
}

  updateGameState(squareName, playerMarker) {
    this.gameState[squareName] = playerMarker
    this.checkIfPlayerWins()
  }

  checkIfPlayerWins() {
    // TODO make this smarter
    const winningIndexes = [
      [0, 1, 2],
      [3, 4, 5],
      [6, 7, 8],
      [0, 3, 6],
      [1, 4, 7],
      [2, 5, 8],
      [0, 4, 8],
      [2, 4, 6],
    ]

    let winner = null

    winningIndexes.forEach((combos) => {
      if (combos.every((combo) => this.gameState[`square-${combo + 1}`] === 'X')) {
        winner = this.playerOne
      } else if (combos.every((combo) => this.gameState[`square-${combo + 1}`] === 'O')) {
        winner = this.playerTwo
      }
    })

    if (Object.values(this.gameState).every((square) => square != '')) {
      alert('Game is a draw!')
    } else if (winner) {
      alert(`${winner} wins!!`)
    }
  }

这些都是相关的函数,如果你在makeMove()函数中看到,我调用eventTarget.insertAdjacentElement,然后我调用updatePlayerTurn()哪个调用checkIfPlayerWins()哪个调用alert(). 函数中的 this 在元素alert()被插入 DOM 之前执行。谁能帮我弄清楚如何在被调用之前等待 DOM 更改发生?谢谢!checkIfPlayerWins()insertAdjacentElementalert()

4

0 回答 0