You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript井字棋点击事件重复触发导致计数异常问题求助

问题原因
  • 核心问题是重复绑定事件监听器未清理:每次调用newclick()时,都会给9个格子各新增1个点击监听函数,之前绑定的旧监听函数没有被移除。每次点击格子时,所有历史绑定的监听函数都会依次执行,所以计数器会多次累加,只有最后一次执行的函数修改的innerHTML会保留,所以界面看起来只新增了一个符号,和计数不匹配。
  • 额外逻辑缺陷:没有判断格子是否已经被占用,已落子的格子依然可以重复触发点击事件。
解决方案

推荐采用更简洁的「单次绑定+回合/状态判断」方案,不需要反复绑定解绑事件,避免重复监听问题:

'use strict'
let turn =1; // 1代表x回合,0代表o回合
let countx = 0;
let counto = 0;
// 存储所有格子id
const cellIds = ['leftTop','centerTop','rightTop','leftCenter','centerCenter','rightCenter','leftBottom','centerBottom','rightBottom'];

// 初始化:只绑定一次事件
cellIds.forEach(id => {
  document.getElementById(id).addEventListener('click', () => handleCellClick(id))
})

function handleCellClick(id) {
  const cell = document.getElementById(id);
  // 先判断格子是否已经落子,已落子直接返回不处理
  if (cell.querySelector('p')) return;
  // 根据当前回合处理落子
  if (turn === 1) {
    cell.innerHTML = '<p>x</p>';
    countx++;
    checkWin();
    turn = 0; // 切换到o回合
  } else {
    cell.innerHTML = '<p>o</p>';
    counto++;
    checkWin();
    turn = 1; // 切换到x回合
  }
}

function checkWin(){
  if(countx==3||counto==3){
    alert('you win');
  }
}

如果你一定要保留原有的「切换回合重新绑定事件」的逻辑,需要先把之前绑定的监听函数移除,注意不能用匿名函数,要把监听函数提取为可复用的有名函数,每次绑定前调用removeEventListener移除旧的监听即可。

内容的提问来源于stack exchange,提问作者Elay Gelbart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 01:09:04