Skip to content
Advertisement

Why does a neighboring element move when I drag and drop an element?

The Problem

I’m creating a game in which the player has a hand of cards. These cards can be moved onto a map (using Mapbox). When a card is moved on the map and it meets some prerequisites, it will be ‘placed’ on that location of the map.

Unfortunately, when I drag a valid card onto the map, it gets ‘placed’ on the location, but the neighboring card moves from the hand to the last location of the placed card.

I made a quick video of the current behavior: https://vimeo.com/459003505

The code

The front-end is a React application and I’m using vanilla javascript to implement the drag and drop functionality. Basically, I have a component containing a number of cards called ProjectCardsHand. The Cards are ProjectCard components. I’m using MapBox to render a map of a city with neighborhoods in App.js.

Here’s the abridged version of my code:

ProjectCardsHand.js

JavaScript

App.js

JavaScript

What I’ve tried I’ve tried a number of things:

  • To follow this guide: https://javascript.info/mouse-drag-and-drop;
  • Set all of the event listener options to true and all of them to false (https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener);
  • Create a flag in the component’s state to indicate props have been received once, so as to avoid assigning the event listeners more than once. This did work to reduce the number of listeners, but didn’t solve the problem;
  • Set flags inside the drag, dragStart and dragEnd functions to check if the activeItem is the one being dragged, but each time activeItem seems to be set to the neighboring item, even though the drag function shouldn’t be called for it.

I’d love to know what I’m doing wrong. How can I fix this so that the project cards that aren’t being dragged stay put?

Advertisement

Answer

I managed to fix it, although it feels more like a workaround. After assigning a card, I loop through the full hand of cards and reset them to the starting position:

JavaScript

The setTranslate() function looks like this:

JavaScript

Next, I ensure the xOffset and yOffset are reset for the item being dragged. These values are used to determine the starting position when starting to drag a card:

JavaScript

So, in sum, it kind of feels like I’m playing a card, then throwing the rest of my hand of cards on the floor, and picking them all up again to make sure they are still in my hand.

Better answers are welcome.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement