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

jQuery开发象棋游戏时如何存储两次点击的元素属性

问题排查

你的代码出问题根本不是var和let的特性差异,是三个硬伤:

  • 跨点击需要留存的选中状态,你只零散存了棋子id和格子value,棋子本身的class、value属性根本没存,更新DOM的时候拿不到对应值。
  • 每次点击事件触发时,你在回调内部声明的value/id/color都是当前点击元素的属性,第一次点棋子存的值,第二次点格子的时候会被直接覆盖,根本留不住。之前用let/const代码直接跑不起来,是因为你把需要跨点击存值的变量声明在了回调内部,回调执行完变量就销毁了,下次点击访问直接报引用错误。
  • 走完一步棋之后你没有重置选中状态,selectedPiece和moveToSquare一直有值,后续点击永远进不了选中判断的分支。另外你写的更新DOM的HTML字符串有语法错误,<td> class=${color}把属性写到了td标签外面,浏览器根本识别不到,DOM结构更新完就乱了。
修复方案

直接把状态变量挪到事件回调外面存全量属性,不要每次重写innerHTML,用jQuery方法直接修改元素属性,走完棋重置状态就行,可直接替换的参考代码如下:

// 注意:这两个变量必须声明在click事件回调的外部,不要写到回调里面
let selectedPiece = null;
let moveToSquare = null;

$(document).on("click", function (event) {
    // 直接拿事件目标元素就行,不用elementFromPoint多此一举
    const $currentEl = $(event.target);
    const elId = $currentEl.attr('id');
    const elValue = $currentEl.attr('value');
    const elClass = $currentEl.attr('class');

    // 点到棋盘外的区域直接跳过
    if (!elId) return;

    // 第一次点击:选中待移动棋子
    if (selectedPiece === null && elId.includes('piece')) {
        selectedPiece = {
            $el: $currentEl,
            id: elId,
            value: elValue,
            pieceClass: elClass
        };
        enlargeBackground();
        return;
    }

    // 第二次点击:选中落子空格,触发行棋
    if (selectedPiece !== null && moveToSquare === null && elId.includes('cell')) {
        moveToSquare = {
            $el: $currentEl,
            id: elId
        };
        move();
        return;
    }
});

// 棋盘DOM更新逻辑
function refreshBoard() {
    // 原棋子位置重置为空白格
    selectedPiece.$el
        .attr('id', 'cell')
        .removeAttr('value')
        .attr('class', 'cell')
        .empty();

    // 目标空格替换为移动后的棋子
    moveToSquare.$el
        .attr('id', selectedPiece.id)
        .attr('value', selectedPiece.value)
        .attr('class', selectedPiece.pieceClass);

    // 走完一步必须重置选中状态,否则后续走棋判断全部失效
    selectedPiece = null;
    moveToSquare = null;
}

// 你原有的move函数保留合法性判断,判断可走之后直接调用refreshBoard()即可
function move() {
    // 原有走棋规则校验逻辑...
    
    // 校验通过后更新棋盘
    refreshBoard();
}
避坑提醒
  • 不要在事件回调内部声明需要跨多次事件留存的变量,这类状态必须放在回调外部的作用域,否则每次触发事件都会重新初始化/覆盖变量值。
  • 更新已有DOM元素的属性优先用.attr()这类原生/jQuery提供的属性修改方法,不要直接拼字符串覆写innerHTML,很容易破坏DOM结构、丢失已绑定的事件。
  • 所有多步操作的状态,在操作流程走完之后必须手动重置为初始值,不然状态判断逻辑会全部混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 08:27:23