HTML Drag and Drop API

HTML Drag and Drop interfaces enable applications to use drag-and-drop features in browsers.

The user may select draggable elements with a mouse, drag those elements to a droppable element, and drop them by releasing the mouse button. A translucent representation of the draggable elements follows the pointer during the drag operation.

You can customize which elements can become draggable, the type of feedback the draggable elements produce, and the droppable elements.

This overview of HTML Drag and Drop includes a description of the interfaces, basic steps to add drag-and-drop support to an application, and an interoperability summary of the interfaces.

Concepts and usage

On the surface, Drag and Drop actually has three distinct use cases: dragging elements within a page, dragging data out of a page, and dragging data into a page. They have subtly different requirements and implementations. However, the Drag and Drop API provides a unified model to think about all these interactions.

At its core, a drag operation involves three things:

It's not necessarily true that all three are under your control, or you need to define them yourself:

  • When dragging external data into a page, there's no draggable item to be defined (for example, it could be a file in the operating system's file explorer).
  • When dragging elements within a page, you often don't need to define any transferred data; you just manipulate the dragged element.
  • When dragging out of the page, there's no drop target to be defined.

We'll look at how each one can be defined and used.

Drag events

HTML drag-and-drop uses the DOM event model and drag events inherited from mouse events. During drag operations, several event types are fired, and some events might fire many times, such as the drag and dragover events.

Event Fires when...
dragstart ...the draggable item starts to be dragged.
drag ...the draggable item is being dragged, every few hundred milliseconds.
dragenter ...the element has a draggable item entering it.
dragleave ...the element has a draggable item leaving it.
dragover ...the element has a draggable item being dragged over it, every few hundred milliseconds.
drop ...the element is a drop target and the draggable item is dropped over it.
dragend ...the draggable item stops being dragged.

Note: The dragstart, drag, and dragend events are fired on the dragged item, and therefore can't fire when dragging a file into the browser from the OS.

Similarly, the dragenter, dragleave, dragover, and drop events are fired on elements that are potential drop targets, and therefore can't fire when dragging an item out of the browser.

For more information, see Drag operations.

Draggable items

In HTML, images, links, and selections are draggable by default. To make an arbitrary element draggable, set the draggable attribute to the value "true".

html
<p id="p1" draggable="true">This element is draggable.</p>

At this point, the element already has the dragging appearance, although it has no behavior defined yet:

For images and links, draggable defaults to true, so you would only set it to false to disable dragging of these elements. For non-draggable elements, the "dragging" gesture usually selects the text instead.

Note: When an element is made draggable, text or other elements within it can no longer be selected in the normal way by clicking and dragging with the mouse. Instead, the user must hold down the Alt key to select text with the mouse, or use the keyboard.

A selection is also draggable. In this case, the source node, or the node on which various events such as dragstart and dragend are fired, is the text node that the drag started on. The selection can partially or fully contain multiple nodes, including text nodes and element nodes, which are all considered dragged simultaneously.

As aforementioned, the dragged item can also be something not on a webpage—for example, a file in the operating system's file explorer. However, only items on the webpage can cause the dragstart and dragend events to fire.

For more information, see the Drag operations guide.

Drag data store

It is not possible to transfer JavaScript objects directly to other webpages, and surely not to external applications, so to transfer data in and out of the webpage, the data must be serialized to a string (or as a File). In Drag & Drop, this string is encapsulated in a DataTransferItem object, which also defines a particular type—typically a MIME type such as text/html—that defines how the string should be interpreted.

Each drag & drop operation has an associated drag data store, which is a DataTransfer object accessible via the DragEvent's dataTransfer property. For the default-draggable items such as images, links, and selections, the drag data is already defined by the browser; for custom draggable elements defined using the draggable attribute, you must define the drag data yourself. The only time to make any modifications to the data store is within the dragstart handler—for the dataTransfer of any other drag event, the data store is unmodifiable.

The setData() method can be used to add an item to the drag data, as shown in the following example.

js
function dragstartHandler(ev) {
  // Add different types of drag data
  ev.dataTransfer.setData("text/plain", ev.target.innerText);
  ev.dataTransfer.setData("text/html", ev.target.outerHTML);
  ev.dataTransfer.setData(
    "text/uri-list",
    ev.target.ownerDocument.location.href,
  );
}

const p1 = document.getElementById("p1");
p1.addEventListener("dragstart", dragstartHandler);

Furthermore, the only time you can read from the data store, apart from the dragstart event, is during the drop event (allowing the drop target to retrieve the data). For all other events, the data store cannot be accessed.

For more information, read Working with the drag data store.

Drop target

By default, elements on a webpage do not accept drops, and if you release the drag, a "fly-black" animation displays indicating that the drag & drop failed. To prevent this, you must make the region of dropping a valid drop target. The drop event only fires on drop targets, and it is the only time you can read the drag data store. Some elements are drop targets by default under certain circumstances, but all elements can elect themselves to become one by cancelling the dragover event with preventDefault().

The following example shows a minimal valid drop target, and also combines the code from the previous examples.

html
<p id="target">Drop Zone</p>
js
const target = document.getElementById("target");

// Cancel dragover so that drop can fire
target.addEventListener("dragover", (ev) => {
  ev.preventDefault();
});
target.addEventListener("drop", (ev) => {
  ev.preventDefault();
  const data = ev.dataTransfer.getData("text/plain");
  ev.target.append(data);
});

For more information, see Specifying drop targets.

Guides

Drag operations

Describes the steps that occur during a drag and drop operation, and what the application is supposed to do within each handler.

Working with the drag data store

Describes how to read and write to the drag data store during a drag and drop operation.

File drag and drop

A hands-on guide implementing a basic interface accepting file drops.

Kanban board with drag and drop

A hands-on guide implementing a Kanban board involving dragging and dropping elements within a webpage.

Interfaces

Examples

Specifications

Specification
HTML

See also