Native Coder
Native Coder

Reputation: 1880

JS Drag and Drop: Dropping one element on top of another replaces dataTransfer data with first elements

I'm writing a simple chess game with react and am attempting to use the drag and drop API to simplify the drag and dropping of the chess pieces. All works as expected, except for when one piece captures another piece. If, for example, white rook captures black pawn, The white rook moves to the black pawns previous position and the black pawn moves off of the board. But the next time I try to move the white rook, it moves the black pawn that was captured instead.

This behavior is 100% consistent no matter which two pieces are used. Piece 1 captures piece 2, and now the dataTransfer data of piece 1 is that of piece2.

I've narrowed this down and I think that problem lies in the dataTransfer object.

Code for the dragStart of the chessPiece

_onDragStart( e ){
    e.dataTransfer.items.clear();
    e.dataTransfer.clearData( "text/plain" );
    e.dataTransfer.effectAllowed = "move";
    e.dataTransfer.dropEffect = "move";
    e.dataTransfer.setData( "text/plain", JSON.stringify( this.metaData ) );
}

Code for the drop handler of the tile

_onDrop( e ){
    this.onDrop({
        index: this.state.index,
        piece: JSON.parse( e.dataTransfer.getData( "text/plain" ) )
    });
}

Upvotes: 4

Views: 589

Answers (1)

Transformer
Transformer

Reputation: 7439

1) Try replace the old piece using dropBefore.replaceWith(yourNewChessPiece);

2) are you Missing the target element Id , not setting it, not sure if your metaData variable has it

Some samples

// cache you element/variables to simplify the later
// I think you are missing this, I cant tell what your this.metaData holds
chessPieceToAddToTile = document.getElementById(data),
dropBefore = ev.target;

// using childNode.replaceWith() to insert the 
// so, *** REPLACE old piece with your new chessPieceToAddToTile Node
// dropBefore Node:
dropBefore.replaceWith(chessPieceToAddToTile);

childNode.replaceWith().... Ref And Node.replaceChild().

Drag Drop replace Node

Troubleshooting: Simplify it a bit so you can see what's happening, something like this in your drag handler, drop handlers

console.log("dragStart: dropEffect = " + ev.dataTransfer.dropEffect + " ; effectAllowed = " + ev.dataTransfer.effectAllowed ; chessPieceToAddToTile... blah blah);

DataTransfer

Upvotes: 2

Related Questions