Taco Steemers

A personal blog.
☼ / ☾

Notes on making drag-and-drop functionality with Javascript

When I wanted to make drag and drop functionality I found there were plenty of tutorials out there. I am adding a few more words on the topic because I had to find workarounds for issues that I didn't find mentioned elsewhere.

When I wanted to make drag and drop functionality I found there were plenty of tutorials out there. This is the page I used myself.

I am adding a few more words on the topic because I had to find workarounds for issues that I didn't find mentioned elsewhere.

Drag and drop has four visual elements:

  • The items that can be dragged
  • The area they originally came from
  • The areas they can be dropped on
  • The area it gets dropped on when the drag action ends

We will call the items that can be dragged the draggables. The areas that a draggable can be dropped on will be called the receivers.

Topics

In this article I want to discuss three topics. For Safari the receivers need an extra attribute, to be able to receive events that indicate the mouse cursor has left the area while dragging. In all browsers the receivers need an extra attribute to be able to properly handle situations where the mouse cursor stays inside receivers, but while doing so has also been moved over an item inside the receiver that is itself not a receiver. The final topic is draggable elements that contain a textarea, and making the textareas function as expected in the Edge and Firefox web browsers.

Event dragexit does not work as expected on Safari

I gave a different background color to receivers while the user was dragging the draggable over the receivers. By using a different background color the user can see which areas are receivers. We don't want to let the user find out by trial and error; dropping the draggable somewhere that cannot receive a draggable will release it from the mouse cursor. The user would have to find the draggable again, and hope the next area would accept the draggable. Adding the different background color when the mouse cursor enters the receiver can be done with an eventhandler added to the ondragenter attribute. My addition comes in when we want to remove the background color after the mouse cursor has passed over the reveiver. On Firefox it is sufficient to add the eventhandler to the ondragexit attribute. For Safari support, and possibly other browsers, we need to add the same event handler to the ondragleave attribute as well.

Event dragenter has quirky behaviour

With the previous improvement we have added a new problem. In all browsers we lose the background color on the receiver if we move the mouse cursor over an unrelated item inside the receiver, even though the mouse cursor has not left the receiver. This is as expected; the item the mouse cursor is now positioned above is not the receiver itself. As a result, the ondragexit or ondragleave event handler will be called.

The problem is that the background color is not added back to the receiver when the mouse cursor is positioned above the receiver again. This can be solved by adding the color-change code to both the dragenter event handler and the dragover event handler.

Text selection in a textearea inside a draggable element

The final problem we need to solve is the text selection behavior in a textearea that is placed inside a draggable. In Edge and Firefox the mouse-based text selection does not work. It does work in Safari. I have not been able to solve this yet. Other applications I am aware of avoid this problem; when the user clicks the draggable element they open a modal screen where the user can edit the contents of the draggable element. I think this work-around also gives the user a better experience because they will always know which draggable they are typing in.