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"
.
<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.
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.
<p id="target">Drop Zone</p>
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
- Copying and moving elements with the
DataTransfer
interface - Copying and moving elements with the
DataTransferListItem
interface
Reference pages for each interface also have individual examples.
Specifications
Specification |
---|
HTML |