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

React/JS象棋游戏中element.remove()与element.append()冲突问题求助

象棋游戏拖拽吃子问题修复

你这段代码的核心问题很明确:执行ev.target.remove()之后,ev.target已经从DOM中被移除了,再调用ev.target.append()根本不会把白棋子加到任何地方,自然屏幕上啥都看不到。

临时DOM操作修复方案

如果先不改React的思路,只修复当前代码,你可以先拿到黑棋子的父容器(也就是棋盘格子),移除黑棋子后,把白棋子加到父元素里:

function drop(ev) {
    ev.preventDefault();
    ev.target.style.backgroundColor = ev.target.dataset.squarecolor;
    let movingPiece = JSON.parse(ev.dataTransfer.getData("Text"));
    
    if (movingPiece.color === 'white' && ev.target?.dataset?.color === 'black' && ev.target.nodeName === 'IMG') {
        // 先拿到黑棋子的父容器(棋盘格子)
        const square = ev.target.parentElement;
        // 移除黑棋子
        ev.target.remove();
        // 把白棋子加到格子里
        square.append(document.getElementById(movingPiece.id));
    }
}

React规范做法(推荐)

但更符合React开发逻辑的是用状态管理棋子位置,而不是直接操作DOM——React是数据驱动视图的,手动操作DOM很容易引发渲染异常:

  1. 用useState维护一个对象,记录每个棋盘格子对应的棋子信息(颜色、类型、ID等)。
  2. 拖拽开始时,记录要移动的棋子的起始位置和信息。
  3. 拖拽结束时,更新状态:把目标格子的棋子替换成当前移动的棋子,同时清空起始格子的棋子。
  4. 组件根据状态自动渲染每个格子的棋子,完全不用手动操作DOM。

简化示例:

import { useState } from 'react';

const ChessBoard = () => {
    // 初始化棋盘状态,key是格子坐标,value是棋子信息
    const [boardState, setBoardState] = useState({
        'a1': { id: 'white-rook-1', color: 'white', type: 'rook' },
        'a8': { id: 'black-rook-1', color: 'black', type: 'rook' },
        // ... 其他棋子
    });

    const handleDragStart = (e, piece, position) => {
        e.dataTransfer.setData("Text", JSON.stringify({ piece, position }));
    };

    const handleDrop = (e, targetPosition) => {
        e.preventDefault();
        const { piece, startPosition } = JSON.parse(e.dataTransfer.getData("Text"));
        
        // 判断是否可以吃子(白吃黑)
        const targetPiece = boardState[targetPosition];
        if (piece.color === 'white' && targetPiece?.color === 'black') {
            setBoardState(prev => ({
                ...prev,
                // 清空起始位置
                [startPosition]: null,
                // 目标位置替换成当前棋子
                [targetPosition]: piece
            }));
        }
    };

    // 渲染棋盘格子和棋子
    return (
        <div className="board">
            {Object.keys(boardState).map(position => (
                <div 
                    key={position}
                    className="square"
                    onDrop={(e) => handleDrop(e, position)}
                    onDragOver={(e) => e.preventDefault()}
                >
                    {boardState[position] && (
                        <img
                            id={boardState[position].id}
                            src={`/images/${boardState[position].color}-${boardState[position].type}.png`}
                            draggable
                            onDragStart={(e) => handleDragStart(e, boardState[position], position)}
                            data-color={boardState[position].color}
                        />
                    )}
                </div>
            ))}
        </div>
    );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:30:50