This article needs a technical review. How you can help.
HTML Drag and Drop interfaces enable applications to use drag and drop features in Firefox and other browsers. For example, with these features, the user can select draggable elements with a mouse, drag the elements to a droppable element, and drop those elements by releasing the mouse button. A translucent representation of the draggable elements follows the mouse pointer during the drag operation.
For web sites, extensions, and XUL applications, you can customize the types of elements that can become draggable elements, and the type of feedback the draggable elements produce, and the droppable elements.
This document is an overview of HTML drag and drop. It includes a description of the interfaces, the basic steps to add drag and drop support to an application and a summary of the interoperability of the interfaces.
Drag Events
HTML drag and drop uses the DOM event model
and drag events
inherit from mouse events
. A typical drag operation begins when a user selects a draggable element with a mouse, moves the mouse to a droppable element and then releases the mouse. During the operations, several event types are fired and some event types might be fired many times (for example the drag
and dragover
event types).
All of the drag event types have an associated global event handler. Each drag event type and drag global attribute has a reference document that describes the event. The following table provides a short description of the event types and a link to the reference documents.
Event | On Event Handler | Description |
---|---|---|
drag |
ondrag |
Fired when an element or text selection is being dragged. |
dragend |
ondragend |
Fired when a drag operation is being ended (for example, by releasing a mouse button or hitting the escape key). (See Finishing a Drag.) |
dragenter |
ondragenter |
Fired when a dragged element or text selection enters a valid drop target. (See Specifying Drop Targets.) |
dragexit |
ondragexit |
Fired when an element is no longer the drag operation's immediate selection target. |
dragleave |
ondragleave |
Fired when a dragged element or text selection leaves a valid drop target. |
dragover |
ondragover |
Fired when an element or text selection is being dragged over a valid drop target (every few hundred milliseconds). |
dragstart |
ondragstart |
Fired when the user starts dragging an element or text selection. (See Starting a Drag Operation.) |
drop |
ondrop |
Fired when an element or text selection is dropped on a valid drop target. (See Performing a Drop.) |
Note that dragstart
and dragend
events are not fired when dragging a file into the browser from the OS.
Interfaces
The HTML drag and drop interfaces are DragEvent
, DataTransfer
, DataTransferItem
and DataTransferItemList
.
The DragEvent
interface has a constructor and one property, the dataTransfer
property which is a DataTransfer
object. DataTransfer
objects include the drag event's state such as the type of drag being done (for example copy
or move
), the drag's data (one or more items) and the type of each drag item (a MIME type). DataTransfer
objects also have methods to add items to the drag's data and to remove a drag item. The DragEvent
and DataTransfer
interfaces should be the only ones needed to add HTML drag and drop capabilities to an application. However, note Firefox supports some Gecko-specific extensions to the DataTransfer
object that may be used, although those extensions will only work on Firefox.
Each DataTransfer
object contains an items
property which is a list
of DataTransferItem
objects. Each DataTransferItem
object represents a single drag item and each item has a kind
property which is the kind of data (either string
or file
) and a type
property which is the data item's type (i.e. MIME type). The DataTransferItem
object also has methods to get the drag item's data.
The DataTransferItemList
object is a list of DataTransferItem
objects. The list object has methods to: add a drag item to the list, remove a drag item from the list and clear the list of all drag items.
A key difference between the DataTransfer
and DataTransferItem
interfaces is that the former uses the synchronous getData()
method to access a drag item's data, whereas the later uses the asynchronous getAsString()
method to access a drag item's data.
Note: the DragEvent
and DataTransfer
interfaces are broadly interoperable with desktop browsers. However, the DataTransferItem
and DataTransferItemList
interfaces have limited browser support. See Interoperability for more information about drag and drop interoperability.
Gecko-specific interfaces
Mozilla and Firefox support some features not in the standard drag and drop model. These are convenience functions to facilitate dragging multiple items and dragging non-string data (such as files). For more information, see Dragging and Dropping Multiple Items. Additionally, see the DataTransfer
reference page for all of the Gecko-specific properties and Gecko-specific methods.
The basics
This section provides a summary of the basic steps to add drag and drop functionality to an application. Each section includes a description of the step, a short code example, and links to additional information.
Identify what is draggable
To make an element draggable requires adding the draggable
attribute plus the ondragstart
global event handler, as shown in the following code sample
function dragstart_handler(ev) { console.log("dragStart"); // Add the target element's id to the data transfer object ev.dataTransfer.setData("text/plain", ev.target.id); } <body> <p id="p1" draggable="true" ondragstart="dragstart_handler(event);">This element is draggable.</p> </body>
See the draggable attribute reference and the Drag operations guide for more information.
Define the drag's data
The application is free to include any number of data items in a drag operation. Each data item is a string
of a particular type
, typically a MIME type such as text/html
.
Each drag event
has a dataTransfer
property that holds the event's data. This property (which is a DataTransfer
object) also has methods to manage drag data. The setData()
method is used to add an item to the drag data, as shown in the following example.
function dragstart_handler(ev) { // Add the drag data ev.dataTransfer.setData("text/plain", ev.target.id); ev.dataTransfer.setData("text/html", "<p>Example paragraph</p>"); ev.dataTransfer.setData("text/uri-list", "https://developer.mozilla.org"); }
For a list of common data types used for drag and drop (such as text, HTML, links, and files), see Recommended Drag Types and for more information about drag data, see Drag Data.
Define the drag image
By default, the browser supplies an image that appears beside the mouse pointer during a drag operation. However, an application may define a custom image by using the setDragImage()
method as shown in the following example.
function dragstart_handler(ev) { // Create an image and then use it for the drag image. // NOTE: change "example.gif" to an existing image or the image // will not be created and the default drag image will be used. var img = new Image(); img.src = 'example.gif'; ev.dataTransfer.setDragImage(img, 10, 10); }
To learn more about drag feedback images, see Setting the Drag Feedback Image.
Define the drag effect
The dropEffect
property is used to control the feedback (typically visual) the user is given during a drag and drop operation. It affects which cursor the browser displays while dragging. For example, when the user hovers over a target drop element, the browser's cursor may indicate the type of operation that will occur.
Three effects may be defined:
copy
indicates that the data being dragged will be copied from its present location to the drop location.
move
indicates that the data being dragged will be moved
link
indicates that some form of relationship or connection will be created between the source and drop locations.
During the drag operation, the drag effects may be modified to indicate that certain effects are allowed at certain locations. If allowed, a drop may occur at that location.
The following example shows how to use this property.
function dragstart_handler(ev) { // Set the drag effect to copy ev.dataTransfer.dropEffect = "copy"; }
See Drag Effects for more details.
Define a drop zone
By default, the browser prevents anything from happening when dropping something onto the HTML element. To change that behavior so that an element becomes a drop zone or is droppable, the element must have both ondragover
and ondrop
event handler attributes. The following example shows how to use those attributes and includes basic event handlers for each attribute.
function dragover_handler(ev) { ev.preventDefault(); // Set the dropEffect to move ev.dataTransfer.dropEffect = "move" } function drop_handler(ev) { ev.preventDefault(); // Get the id of the target and add the moved element to the target's DOM var data = ev.dataTransfer.getData("text"); ev.target.appendChild(document.getElementById(data)); } <body> <div id="target" ondrop="drop_handler(event);" ondragover="dragover_handler(event);">Drop Zone</div> </body>
Note each handler calls preventDefault()
to prevent additional event processing for this prevent (such as touch events or pointer events).
For more information, see Specifying Drop Targets.
Handle the drop effect
The handler for the drop
event is free to process the drag data in an application specific way. Typically, an application will use the getData()
method to retrieve drag items and process them accordingly. Additionally, application semantics may differ depending on the value of the dropEffect
and/or the state of modifier keys.
The following example shows a drop handler getting the source element's id from the drag data and then using the id to move the source element to the drop element.
function dragstart_handler(ev) { ev.preventDefault(); // Add the target element's id to the data transfer object ev.dataTransfer.setData("text/plain", ev.target.id); ev.dropEffect = "move"; } function drop_handler(ev) { ev.preventDefault(); // Get the id of the target and add the moved element to the target's DOM var data = ev.dataTransfer.getData("text"); ev.target.appendChild(document.getElementById(data)); } <body> <p id="p1" draggable="true" ondragstart="dragstart_handler(event);">This element is draggable.</p> <div id="target" ondrop="drop_handler(event);" ondragover="dragover_handler(event);">Drop Zone</div> </body>
For more information, see Performing a Drop.
Drag end
At the end of a drag operation, the dragend
event fires at the source element - the element that was the target of the drag start. This event fires whether the drag completed or was canceled. The dragend
event handler can check the value of the dropEffect
property to determine if the drag operation succeeded or not.
For more information about handling the end of a drag operation, see Finishing a Drag.
Interoperability
As can be seen in the DataTransferItem interface's Browser Compatibility table, drag-and-drop interoperability is relatively broad among desktop browsers (except the DataTransferItem
and DataTransferItemList
interfaces have less support). This data also indicates drag and drop support among mobile browsers is very low.
Examples and demos
- Copying and moving elements with the
DataTransfer
interface - Copying and moving elements with the
DataTransferListItem
interface - Dragging and dropping files; Firefox only: https://jsfiddle.net/9C2EF/
- Dragging and dropping files; All browsers: https://jsbin.com/hiqasek/