Understanding Drag & Drop

The HTML Drag and Drop API allows users to drag supported elements and drop them onto designated areas of a webpage.

HTML can identify content as draggable, while JavaScript responds to drag-and-drop events and controls what happens during the operation. The API also provides the DataTransfer object for transferring information between the dragged item and its drop target.

Making Elements Draggable

Most HTML elements are not draggable by default. The global draggable attribute can identify an element that should participate in a drag-and-drop operation.

<div id="drag-item" draggable="true">Drag Me</div>

The values for draggable are true and false. Unlike a Boolean HTML attribute, simply writing draggable without a value does not mean true.

Images and links can have default native dragging behavior, while other elements generally need draggable="true" when they are intended to be dragged with this API.

Drag Events

A drag-and-drop operation can produce several events as the user begins dragging, moves over potential targets, drops the item, and finishes the operation.

Event Purpose
dragstart Occurs when the user begins dragging an item.
drag Occurs while an item is being dragged.
dragenter Occurs when a dragged item enters a potential drop target.
dragover Occurs while a dragged item is over a potential drop target.
dragleave Occurs when a dragged item leaves a potential drop target.
drop Occurs when the item is dropped on an allowed target.
dragend Occurs when the drag operation finishes.

An application does not necessarily need to handle every drag event. The events used depend on the behavior the webpage needs to provide.

The dragstart Event

The dragstart event occurs when the user begins dragging an element. It is commonly used to identify the information associated with the dragged item.

const item = document.querySelector("#drag-item");

item.addEventListener("dragstart", (event) => {
  event.dataTransfer.setData("text/plain", event.target.id);
});

The event's dataTransfer property provides access to a DataTransfer object. In this example, the ID of the dragged element is stored as plain text.

The DataTransfer Object

The DataTransfer object holds information associated with a drag-and-drop operation.

The setData() method stores data using a specified format:

event.dataTransfer.setData("text/plain", "drag-item");

The getData() method retrieves stored data during the appropriate stage of the operation:

const id = event.dataTransfer.getData("text/plain");

The object also provides features for working with dragged files, allowed operations, drop effects, and the visual image shown during a drag.

Creating a Drop Target

A drop target is an element that accepts the dragged content. It can be an ordinary HTML element identified by JavaScript as part of the drag-and-drop interaction.

<div id="drop-zone">Drop Here</div>

Creating the element alone does not automatically make it accept a drop. The default browser behavior for the relevant drag event must normally be handled before the drop event can occur.

The dragover Event

The dragover event occurs repeatedly while an item is being dragged over a potential drop target.

Calling preventDefault() during dragover indicates that the location can accept a drop.

const dropZone = document.querySelector("#drop-zone");

dropZone.addEventListener("dragover", (event) => {
  event.preventDefault();
});

Without this step, the browser's default behavior generally prevents the element from becoming a valid drop target.

The drop Event

The drop event occurs when the user releases the dragged item over an allowed drop target.

dropZone.addEventListener("drop", (event) => {
  event.preventDefault();

  const id = event.dataTransfer.getData("text/plain");
  const item = document.getElementById(id);

  dropZone.appendChild(item);
});

This example retrieves the ID stored during dragstart, finds the corresponding element, and moves that element into the drop zone.

The dragend Event

The dragend event occurs on the dragged element when the drag operation ends, whether or not the item was successfully dropped on a target.

item.addEventListener("dragend", () => {
  console.log("Drag operation finished.");
});

This event can be useful for removing temporary visual styles or performing other cleanup after a drag operation.

Complete Drag and Drop Example

The following example combines a draggable HTML element with a drop target and the JavaScript needed to move the item.

<div id="drag-item" draggable="true">Drag Me</div>

<div id="drop-zone">Drop Here</div>

<script>
const item = document.querySelector("#drag-item");
const dropZone = document.querySelector("#drop-zone");

item.addEventListener("dragstart", (event) => {
  event.dataTransfer.setData("text/plain", event.target.id);
});

dropZone.addEventListener("dragover", (event) => {
  event.preventDefault();
});

dropZone.addEventListener("drop", (event) => {
  event.preventDefault();

  const id = event.dataTransfer.getData("text/plain");
  const draggedItem = document.getElementById(id);

  dropZone.appendChild(draggedItem);
});
</script>

The draggable element supplies the item, dragstart stores its ID, dragover allows the drop, and drop moves the element into its new location.

Play in Editor

Drag and Drop Accessibility

Drag-and-drop interactions should not require dragging as the only way to perform an important action. Some users navigate with a keyboard, use assistive technology, or have difficulty performing precise pointer movements.

Provide another way to accomplish the same task when dragging is required for functionality. Depending on the interface, alternatives can include buttons, menus, keyboard controls, or other clearly labeled actions.

Keyboard focus should remain visible, instructions should explain the available interaction, and changes caused by the operation should be understandable without relying only on visual movement.

Touch Devices

Native HTML drag-and-drop behavior was designed primarily around pointer and mouse-style interactions, and its behavior on touch devices can differ between browsers and devices.

Do not assume that an interaction that works with a desktop mouse will provide the same experience on a touchscreen. Test important drag-and-drop interfaces on the browsers and devices the website intends to support.

For interfaces where touch interaction is essential, other event models and application-specific controls may provide a more predictable experience than relying exclusively on native HTML drag and drop.

Common Drag and Drop Mistakes

Mistake Better Approach
Forgetting draggable="true" Explicitly make appropriate elements draggable.
Writing draggable as if it were a Boolean attribute Use the enumerated value draggable="true".
Expecting every element to accept drops automatically Handle dragover and prevent its default behavior for valid drop targets.
Trying to retrieve transferred data at the wrong stage Use the DataTransfer object according to the drag-and-drop event model.
Making dragging the only available interaction Provide an accessible alternative for important functionality.
Testing only with a desktop mouse Consider keyboard, assistive technology, touch, and other input methods.

Best Practices

  • Use draggable="true" only on elements that are intended to participate in drag-and-drop interactions.
  • Use dragstart to prepare the information needed for the operation.
  • Use DataTransfer to transfer appropriate data between the drag source and drop target.
  • Handle dragover correctly when an element should accept a drop.
  • Clearly indicate which items can be dragged and which locations accept them.
  • Do not make dragging the only method for completing an important action.
  • Provide keyboard-accessible alternatives when appropriate.
  • Do not rely on color or visual movement alone to communicate the result of an interaction.
  • Test drag-and-drop interfaces with different browsers, devices, and input methods.
  • Keep drag-and-drop interactions simple enough that their purpose and result are clear to the user.

Summary

The HTML Drag and Drop API combines the draggable attribute with JavaScript drag events and the DataTransfer object. A typical operation begins with dragstart, allows a destination through dragover, and processes the result with drop.

Drag-and-drop interfaces should also provide accessible alternatives and be tested beyond desktop mouse interaction. Next, we will look at the Geolocation API and how a webpage can request geographic location information with the user's permission.