无法实现井字棋(Tic Tac Toe)游戏玩家轮流切换问题求助
问题分析与解决方案
问题根源
- 事件绑定时机错误:你在
playerMove函数中遍历单元格时,仅在函数执行瞬间根据player-turn类的存在情况为单元格绑定点击事件。第一次调用playerMove时,ticTacToeBoard带有player-turn类,所有单元格都绑定了「X转O」的点击逻辑,后续即使切换类名,这些事件也不会被替换,导致else分支永远无法触发。 - 冗余条件判断:
else if (ticTacToeBoard.classList.contains("player-turn") === false)完全可以简化为else,因为contains方法返回布尔值,非真即假。 - 缺少重复点击限制:当前代码允许同一单元格被多次点击,会不断追加字符,不符合井字棋规则。
修正后的代码
"use strict"; const gameClock = document.querySelector(".clock"); const playerTitle = document.querySelector(".player-title"); const ticTacToeBoard = document.querySelector(".tic-tac-toe-container"); const cells = document.querySelectorAll(".cell"); const startPauseBtn = document.querySelector(".start-btn"); // 修正选择器,原代码遗漏类选择器的点 const resetBtn = document.querySelector(".resetBtn"); let currentPlayer = "X"; ticTacToeBoard.classList.add("player-turn"); playerTitle.innerHTML = "Player: 1"; // 初始化玩家标题 // 统一的单元格点击处理逻辑 const handleCellClick = (cell) => { // 单元格已有内容则直接返回,禁止重复点击 if (cell.textContent.trim() !== "") return; cell.append(currentPlayer); // 根据当前玩家切换状态 if (currentPlayer === "X") { currentPlayer = "O"; playerTitle.innerHTML = "Player: 2"; } else { currentPlayer = "X"; playerTitle.innerHTML = "Player: 1"; } ticTacToeBoard.classList.toggle("player-turn"); }; const playerMove = () => { // 给所有单元格绑定统一的点击事件 cells.forEach((cell) => { cell.addEventListener("click", () => handleCellClick(cell)); }); }; // 调用函数初始化事件绑定 playerMove();
关键修正点
- 统一事件处理:不再根据初始化状态绑定不同事件,而是在每次点击时实时判断当前玩家状态,执行切换逻辑。
- 拦截重复点击:通过判断单元格内容是否为空,避免同一位置多次落子。
- 修正选择器错误:修复了
startPauseBtn的选择器,确保能正确选中按钮。 - 初始化玩家标题:添加初始状态的玩家标题,避免首次点击前标题为空。
内容的提问来源于stack exchange,提问作者Deshawn Reid
相关产品推荐
相关产品推荐

