Drag'n'Drop Event Handling Gotchas I Wish I Knew Earlier

16 Aug · by Tim Kamanin · 2 min read

I'll explain the gotchas in a plain HTML/JS pseudocode, but these concepts apply to every way you might write your JS code: react, vue, svelte, vanilla, whatever.

Gotcha #1: If you want a div to accept drop event and listen to drag events i.e. become "droppable" there are two conditions that need to be fulfilled:

1) The element should provide a handler for ondragover event:

<div id="droparea" ondragover="handleDragOver();"></div>

2) The element should provide a handler for ondop event

<div id="droparea" ondrop="handleDrop();"></div>

As a result it should look like:

<div id="droparea" ondragover="handleDragOver();" ondrop="handleDrop();"></div>

And now you need to know the second gotcha:

Gotcha #2: In order to have the drop event happen on a div element, you must cancel "ondragenter" and "ondragover" events.

So what we've done above is not enough. We need to stop propagation and prevent default behaviors for ondragenter and ondragover events.

As a result, your pseudocode should look like this:

<div id="droparea"
     ondragenter=""event.stopPropagation(); event.preventDefault(); handleDragEnter(event);"
     ondragover="event.stopPropagation(); event.preventDefault(); handleDragOver(event);"
     ondrop="event.stopPropagation(); event.preventDefault(); handleDrop(event);">

Gotcha #3: Google Chrome console has a bug and shows event.dataTransfer.files as empty but it's not!

When you process dropped files in the onDrop handler and want to console.log event and check if it contains any files you won't see a file list in the output:

onDropHandler(event) {

// Shows event.dataTransfer.files and event.dataTransfer.items as empty 

That's a little async-related gotcha. To solve this, instead, console.log event.dataTransfer.files directly:

onDropHandler(event) {

// Now should be good!

Enjoy dragging and dropping!

Want to get more 🔥 tips like this one?

Subscribe to get notified about new dev tutorials