我正在通过构建一个井字游戏应用程序来练习 html/vanilla JS。我在 board square s 中添加了一个事件监听器<div>
,并使用 X 和 O 创建元素并将它们插入到 DOM 中,然后调用一个函数来检查是否有获胜者。该checkIfPlayerWins()
函数进行一些检查,然后调用,alert
如果玩家获胜或平局。
我遇到的问题是,如果玩家获胜,则会在将 X 或 O 插入 DOM 之前调用警报,这看起来很有趣。我不想使用 a setTimeout
,因为它看起来有点 hacky。我尝试了async
/await
并new 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()
insertAdjacentElement
alert()