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

开发井字棋游戏时无法为被点击的div元素添加class的问题

问题原因与解决方案

你写的事件绑定逻辑本身是符合JS事件机制的:默认情况下,通过addEventListener绑定的回调函数中,this关键字就是指向触发当前事件的DOM元素,也就是你点击的tile。如果出现点击后没有给当前元素加类的情况,基本都是以下几种常见问题导致的,对应解决方案如下:

问题1:DOM未加载完成就执行了绑定逻辑

getElementsByClassName返回的是动态HTML集合,如果你的脚本放在head标签里,执行时页面的tile元素还没渲染,拿到的gameBoard是空集合,后续的事件绑定完全没有生效。

解决方案

把全部JS代码放在body标签的末尾,或者包裹在DOM加载完成的事件回调中:

document.addEventListener('DOMContentLoaded', function() {
  // 你原来的所有代码放在这个回调内部
  var gameBoard = document.getElementsByClassName("tile")
  var playerOne = {
    "turn": true,
    "class": "cross" 
  }
  var playerTwo = {
    "turn": false,
    "class": "naught" 
  }
  for (let i = 0; i < gameBoard.length; i++ ) {
    gameBoard[i].addEventListener("click", takeTurn)
  }
})

问题2:this指向被其他逻辑修改

如果你的代码中存在其他修改takeTurn指向的逻辑(比如用了箭头函数、bind绑定等),会导致this不指向触发事件的元素。可以直接从事件对象中获取点击目标,写法更稳妥,兼容性也更好。

解决方案

修改takeTurn函数,从事件参数中取触发元素,还可以补充判断避免重复点击同一格子、切换玩家回合的逻辑:

function takeTurn (e) {
  // e.target 就是实际触发本次点击事件的DOM元素
  const currentTile = e.target
  // 已经有棋子的格子不能重复点击
  if(currentTile.classList.contains('cross') || currentTile.classList.contains('naught')) return
  // 根据当前回合给格子加对应类
  if(playerOne.turn) {
    currentTile.classList.add(playerOne.class)
  } else {
    currentTile.classList.add(playerTwo.class)
  }
  // 切换玩家回合
  playerOne.turn = !playerOne.turn
  playerTwo.turn = !playerTwo.turn
}

内容的提问来源于stack exchange,提问作者Sean Jones

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 04:06:04