JavaScript 8x8棋盘开发:如何识别点击单元格并与随机选中单元格进行校验
问题分析与解决方案:判断用户点击是否命中电脑随机选中的单元格
我来帮你拆解下当前遇到的问题,然后给出具体的修复方案~
核心错误点
你现在的代码主要有两个关键问题导致对比失效:
- 事件绑定的参数传递错误:你给
respondToClick定义了cells参数,但通过addEventListener绑定事件时,浏览器只会自动传入event参数,不会额外传递cells,所以函数内部的cells实际是undefined。 - 元素对比逻辑错误:你用
event.target.nodeName.toLowerCase() == cells[0]做判断——左边是字符串(比如"td"),右边是DOM元素对象,类型完全不同,永远不可能相等,应该直接对比DOM元素本身。
修复后的完整实现
第一步:优化随机单元格生成逻辑(更直观)
原来的8进制转换方式有点绕,我们可以直接用数学计算得到行列坐标,同时加入去重逻辑避免重复选中同一个单元格:
function getRandomArbitrary(min, max) { return Math.floor(Math.random() * (max - min) + min); // 用floor避免生成64这个超出范围的数 } const computerSelectedCells = []; const usedIndices = new Set(); // 生成5个不重复的随机单元格(不设置背景色,隐藏电脑选中状态) while (computerSelectedCells.length < 5) { const randomIndex = getRandomArbitrary(0, 64); if (!usedIndices.has(randomIndex)) { usedIndices.add(randomIndex); const row = Math.floor(randomIndex / 8); const col = randomIndex % 8; computerSelectedCells.push(ChessTable.rows[row].cells[col]); } }
第二步:修复点击响应函数
利用闭包特性让函数能访问到外部的computerSelectedCells数组,同时修正元素对比逻辑:
function respondToClick(event) { const clickedCell = event.target; if (clickedCell.nodeName.toLowerCase() === 'td') { // 设置点击后的默认绿色背景 clickedCell.style.backgroundColor = "green"; // 遍历电脑选中的单元格,判断是否命中 const isCorrect = computerSelectedCells.some(cell => cell === clickedCell); if (isCorrect) { alert("correct!"); // 可以给命中的单元格设置特殊颜色标记 clickedCell.style.backgroundColor = "orange"; } } } // 绑定事件,无需额外传参,函数通过闭包访问computerSelectedCells ChessTable.addEventListener("click", respondToClick);
额外优化建议
- 避免重复提示:可以新增一个
hitCells数组记录已命中的单元格,防止用户重复点击同一个命中单元格时反复触发alert - 游戏结束判定:当
hitCells的长度等于computerSelectedCells的长度时,提示用户“所有目标已命中,游戏结束” - 样式优化:可以用CSS类代替直接修改
style属性,方便统一管理单元格样式
内容的提问来源于stack exchange,提问作者user17712660
相关产品推荐
相关产品推荐

