100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

How Does the HTML5 Drag and Drop API Work?

Learn how the HTML5 Drag and Drop API works — dragstart, dragover, drop events, and the DataTransfer object.

mediumQ188 of 224 in Web Development Est. time: 5 minsLast updated:
Open Code Lab

Expected Interview Answer

The HTML5 Drag and Drop API lets any element with draggable="true" be picked up and moved via a sequence of drag events (dragstart, dragover, drop, and others) that carry data through a DataTransfer object, letting a drop target read that data and decide how to handle it.

Making an element draggable is as simple as setting the draggable attribute, after which the browser fires dragstart on that element when the user begins dragging; the handler typically calls event.dataTransfer.setData(mimeType, data) to attach a payload. As the dragged item moves over potential drop targets, dragenter and dragover fire repeatedly on those targets, and crucially the dragover handler must call event.preventDefault() or the browser rejects the drop entirely, since the default behavior for most elements is to disallow dropping. When the user releases the mouse over a valid target, the drop event fires there, where event.dataTransfer.getData(mimeType) retrieves the payload set at dragstart, and the handler decides what to do with it (reorder a list, upload a file, move a DOM node). Finally dragend fires on the original source element regardless of whether the drop succeeded, letting the source clean up (e.g. remove a drag ghost element or reset opacity). The same API also handles native OS file drops, where dataTransfer.files gives access to File objects dragged in from the desktop.

  • Native browser support means no external library needed for basic drag interactions
  • DataTransfer carries arbitrary data (text, HTML, files) between source and target
  • Works uniformly for both in-page element reordering and OS file drops
  • Fine-grained events (dragenter/dragover/dragleave/drop) allow precise visual feedback

AI Mentor Explanation

Drag and drop is like a fielder picking up a ball at one spot on the ground, carrying it while call-outs track its path, and only actually handing it off if the receiving fielder signals readiness by raising a hand — otherwise the throw is refused. The moment the ball leaves the first fielder’s hand, an announcement fires; as it travels over other fielders, each gets a heads-up call; and only the fielder who explicitly signals "ready" receives it and decides what to do with it. That pickup-travel-signal-required-handoff sequence is exactly the dragstart, dragover-with-preventDefault, and drop events.

Step-by-Step Explanation

  1. Step 1

    Mark elements draggable

    Set draggable="true" on the source element(s) to enable native drag behavior.

  2. Step 2

    Handle dragstart

    Attach a payload via event.dataTransfer.setData(mimeType, data) when the drag begins.

  3. Step 3

    Handle dragover on targets

    Call event.preventDefault() in the dragover handler on any element that should accept a drop.

  4. Step 4

    Handle drop and dragend

    Read the payload with dataTransfer.getData() in drop; clean up source state in dragend regardless of outcome.

What Interviewer Expects

  • Knowledge that dragover must call preventDefault() for a drop to be allowed
  • Understanding of the DataTransfer object as the data-carrying mechanism
  • Awareness of the full event sequence: dragstart, dragenter/dragover, drop, dragend
  • Mention that the same API handles native OS file drops via dataTransfer.files

Common Mistakes

  • Forgetting event.preventDefault() in dragover, which silently blocks all drops
  • Not cleaning up source element state in dragend when a drop is cancelled
  • Assuming drop only fires for in-page elements, missing OS file drop support
  • Reading dataTransfer data in the wrong event (e.g. trying to read in dragover instead of drop)

Best Answer (HR Friendly)

The Drag and Drop API works through a chain of events — dragstart when you pick something up, dragover as you move it across possible targets, and drop when you release it. The key gotcha I always remember is that you must call preventDefault in the dragover handler, otherwise the browser blocks the drop by default.

Code Example

Minimal drag-and-drop reordering
const items = document.querySelectorAll('.item')
const list = document.getElementById('list')

items.forEach(item => {
  item.setAttribute('draggable', 'true')
  item.addEventListener('dragstart', e => {
    e.dataTransfer.setData('text/plain', item.dataset.id)
    item.classList.add('dragging')
  })
  item.addEventListener('dragend', () => item.classList.remove('dragging'))
})

list.addEventListener('dragover', e => {
  e.preventDefault() // required, or drop is rejected
})

list.addEventListener('drop', e => {
  e.preventDefault()
  const draggedId = e.dataTransfer.getData('text/plain')
  const draggedEl = document.querySelector(`[data-id="${draggedId}"]`)
  list.appendChild(draggedEl) // move to end of list
})

Follow-up Questions

  • Why does the drop event fail silently if preventDefault is not called in dragover?
  • How would you handle a native OS file dropped onto a browser page?
  • What are the accessibility limitations of the native Drag and Drop API and how would you mitigate them?
  • How does dataTransfer.effectAllowed differ from dropEffect?

MCQ Practice

1. What must a dragover handler call for a drop to be allowed on that element?

The browser blocks dropping by default; preventDefault() in dragover explicitly opts the element in.

2. Where is drag payload data attached to the DataTransfer object?

dataTransfer.setData() is called in dragstart, then read later via getData() in the drop handler.

3. What lets the Drag and Drop API handle files dragged in from the desktop?

dataTransfer.files exposes File objects when the user drags files in from outside the browser.

Flash Cards

What attribute makes an element draggable?draggable="true"

What must dragover call to allow a drop?event.preventDefault()

How is data passed from source to target?Via dataTransfer.setData() at dragstart and dataTransfer.getData() at drop.

What event always fires on the source, drop or not?dragend

1 / 4

Continue Learning