




在开发井字棋(tic tac toe)等回合制游戏时,需确保每个格子仅能被标记一次(如填入 "x" 或 "o"),后续点击不可覆盖已有内容。本文介绍两种可靠方案:现代浏览器推荐使用 `addeventlistener` 的 `{ once: true }` 选项;兼容旧版 ie 则可通过手动移除监听器实现相同效果。
在井字棋游戏中,一个核心交互约束是:每个棋盘格子只能被落子一次。若用户重复点击已标记的格子,当前逻辑(如 e.currentTarget.textContent = getActivePlayer().marker)会错误地覆盖原有内容,破坏游戏规则与状态一致性。
最简洁、语义清晰的解决方案是利用 addEventListener 的 once 选项:
board.forEach(element => {
element.addEventListener('click', playRound, { once: true });
});该选项告诉浏览器:此事件监听器在首次触发后自动移除,无需手动清理,也无需在回调中检查状态。它天然满足“只执行一
次”的需求,代码更健壮、可读性更高,且避免了竞态条件或重复判断逻辑。
✅ 优势:
⚠️ 注意兼容性:
{ once: true } 不支持 Internet Explorer(IE),但已被所有现代浏览器(Chrome ≥55、Firefox ≥50、Edge ≥79、Safari ≥15.4)广泛支持。如需支持 IE,可采用手动移除监听器的兼容方案:
const board = document.querySelectorAll('.square');
board.forEach(element => {
const handleClick = (e) => {
playRound(e); // 执行你的原始逻辑
element.removeEventListener('click', handleClick); // 立即解绑
};
element.addEventListener('click', handleClick);
});此方式在回调末尾显式调用 removeEventListener,效果等同于 once: true,且完全兼容 IE9+。
? 额外建议:
综上,通过 once: true 或手动解绑,即可优雅、安全、跨浏览器地实现格子内容“一次性写入、永久锁定”,让井字棋的状态管理既简洁又可靠。