使用模块设计模式开发井字棋 重启触发removeChild类型错误求助
问题根因
- 首先是点击事件重复绑定:你把
gameFlow函数放在setInterval中周期性执行,每次执行都会给所有.gameBox元素追加绑定一次点击事件。玩家点击格子时,会同时触发多次绑定的回调,同一个格子会被插入多个X/O的<p>元素。 - 其次是重启清节点逻辑缺校验:执行
el.removeChild(el.firstChild)时,如果某个.gameBox没有子节点,el.firstChild返回值为null,传入removeChild就会触发你遇到的参数类型错误;就算有子节点,你只删除第一个子节点,重复绑定插入的多个节点残留,就会出现二次重启后部分元素清不掉的问题。
修复方案
1. 修复事件重复绑定问题
给gameFlow加绑定标记,确保事件仅绑定一次即可:
// 全局新增绑定状态标记 let isEventBinded = false const gameFlow = () => { const board = gameBoard.getBoard() const box = document.querySelectorAll('.gameBox') let x = true // Put this in the global scope if there is an error. const renderX = (e) => { for (let i = 0; i < board.length; i++) { const target = e.target const data = target.getAttribute('data-index') const el = document.createElement('p') el.classList.add('elstyle') if (board[i] === '') { if (i === Number(data)) { gameBoard.fillBoard(i, 1, '❌') el.textContent = `${board[i]}` target.appendChild(el) x = false } } } } const renderO = (e) => { for (let i = 0; i < board.length; i++) { const target = e.target const data = target.getAttribute('data-index') const el = document.createElement('p') el.classList.add('elstyle') if (board[i] === '') { if (i === Number(data)) { gameBoard.fillBoard(i, 1, '⭕') el.textContent = `${board[i]}` target.appendChild(el) x = true } } } } // 仅首次执行时绑定事件 if (!isEventBinded) { box.forEach(el => el.addEventListener('click', ((e) => { if (x) { renderX(e) } else { renderO(e) } }))) isEventBinded = true } }
如果需要每次重启重置下棋方x的状态,把x变量移到gameFlow外层维护即可。
2. 优化重启清空节点逻辑
直接清空元素所有内容,避免判断节点和漏删的问题:
const restartGame = (() => { const mainThree = document.getElementById('mainThree') const restart = document.getElementById('restartBtn') const boxes = document.querySelectorAll('.gameBox') restart.addEventListener('click', () => { mainThree.style.display = 'none' gameBoard.setBoard() boxes.forEach(el => { // 直接清空所有子内容,简单稳妥 el.innerHTML = '' }) }) })()
额外优化建议
gameFlow里只有胜负检测、状态同步类逻辑需要定时执行,事件绑定逻辑完全不需要周期性运行,建议把事件绑定单独抽出来在页面初始化时执行一次即可,不需要放在setInterval中,减少不必要的性能开销。
内容的提问来源于stack exchange,提问作者Rabten
相关产品推荐
相关产品推荐

