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

嵌套井字棋:点击单元格无法在对应位置生成X/O的问题

解决嵌套井字棋点击单元格生成X/O的问题

问题根源

  1. 选错目标单元格:document.querySelector(".cell")只会匹配页面中第一个.cell元素,不管点击哪个格子,SVG都往第一个单元格里加。
  2. 未传递点击目标:play()函数不知道当前点击的是哪个单元格,无法对应操作目标。
  3. 未检查单元格状态:重复点击同一单元格会不断叠加X/O,不符合游戏规则。
  4. 逻辑顺序错误:else分支里turn = "x"写在return之后,永远不会执行,导致一直生成O。

修复方案

  1. 给play函数传递点击目标:将单元格的onclick改为onclick="play(this)",让函数获取当前点击的单元格元素。
  2. 增加单元格占用检查:判断单元格内是否已有子元素,有则直接返回,避免重复生成。
  3. 修正目标元素操作:直接使用传入的单元格元素进行操作,不再用querySelector查找第一个匹配项。
  4. 调整else分支代码顺序:将turn = "x"放在return之前,确保回合切换生效。

修改后的完整代码

function create_elements_from_html(n, html){
    const template = document.createElement("template")
    let htmlaux = ``
    // 声明循环变量a,避免全局污染
    for (let a = 0; a < n; a += 1){
        htmlaux += html
    }

    template.innerHTML = htmlaux
    return template.content;
}

let turn = "x"

// 接收当前点击的单元格作为参数
function play(cell){
    // 检查单元格是否已被占用,有内容则直接返回
    if (cell.children.length > 0) return;

    let svgContent;
    if (turn === "x"){
        svgContent = create_elements_from_html(1, `<svg viewBox="0 0 100 100"> <path class="x_cell_path" d="M 10 10 L 90 90 Z M 10 90 L 90 10"> </svg>`)
        turn = "o"
    } else {
        svgContent = create_elements_from_html(1, `<svg viewBox="0 0 100 100"> <circle class="o_cell_path" r="40" cx="50" cy="50"> </svg>`)
        turn = "x"
    }
    // 将SVG添加到当前点击的单元格中
    cell.appendChild(svgContent)
}

let big_board = create_elements_from_html(1, 
    `<div class="big_board">
        <svg class="small_board_svg" viewBox="0 0 100 100">
            <path class="big_board_path" d="M 33.33333 0 l 0 100 M 66.66666 0 l 0 100 M 0 33.33333 l 100 0 M 0 66.66666 l 100 0">
            </svg>
    </div>`)

document.body.appendChild(big_board)

let small_board = create_elements_from_html(9, 
    `<div class="small_board">
        <svg class="small_board_svg" viewBox="0 0 100 100">
            <path class="small_board_path" d="M 33.33333 0 l 0 100 M 66.66666 0 l 0 100 M 0 33.33333 l 100 0 M 0 66.66666 l 100 0">
            </svg>
    </div>`)
document.querySelector(".big_board").appendChild(small_board)

for (let i = 0; i < 9; i++) {
    let cell = create_elements_from_html(1, `
    <div class="cell" data-cell onclick="play(this)">
    </div>`)
    document.querySelectorAll(".small_board").forEach((board) => board.appendChild(cell.cloneNode(true)))
}

额外优化

  • 给循环变量a添加let声明,避免全局变量污染。
  • 合并SVG生成逻辑,减少重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 12:17:03