Drag and Drop API
This lesson explains Drag and Drop API with clear examples, use cases, and best practices so you can use HTML5 APIs confidently in real web applications.
HTML5 Drag and Drop API Overview
The HTML5 Drag and Drop API allows users to drag elements, text, links,
images, and files from one location to another inside a web page or from
the operating system into the browser. It is commonly used for file
uploads, sortable lists, kanban boards, dashboards, image galleries,
page builders, and custom UI interactions.
Drag and Drop works by making an element draggable, listening to drag
events, storing transferred data with dataTransfer, and
handling the drop target. For production applications, drag-and-drop
interfaces should also support keyboard controls and accessible status
messages.
| Feature | Description |
| API Name | HTML5 Drag and Drop API |
| Main Attribute | draggable="true" |
| Main Object | event.dataTransfer |
| Common Events | dragstart, dragover, drop |
| Data Types | Text, HTML, URLs, files, and custom data. |
| Common Uses | File uploads, sortable lists, boards, builders, galleries. |
Basic Drag and Drop Example
<div
id="card"
draggable="true">
Drag Me
</div>
<div id="dropZone">
Drop Here
</div>
<script>
const card = document.querySelector("#card");
const dropZone = document.querySelector("#dropZone");
card.addEventListener("dragstart", (event) => {
event.dataTransfer.setData("text/plain", card.id);
});
dropZone.addEventListener("dragover", (event) => {
event.preventDefault();
});
dropZone.addEventListener("drop", (event) => {
event.preventDefault();
const id =
event.dataTransfer.getData("text/plain");
const draggedElement =
document.getElementById(id);
dropZone.appendChild(draggedElement);
});
</script>
This example makes a card draggable and allows it to be dropped into a
target container. The dragover event must call
preventDefault() to allow dropping.
Drag and Drop Events
The Drag and Drop API provides several events for tracking the complete
drag lifecycle from start to finish.
| Event | Triggered When | Common Use |
dragstart | User starts dragging an element. | Store data using dataTransfer. |
drag | Element is being dragged. | Track drag movement. |
dragenter | Dragged item enters a drop target. | Highlight the target. |
dragover | Dragged item is over a drop target. | Call preventDefault() to allow drop. |
dragleave | Dragged item leaves a drop target. | Remove highlight styles. |
drop | Item is dropped on a valid target. | Move, upload, or process dropped data. |
dragend | Drag operation finishes. | Clean up styles and temporary state. |
DataTransfer Object
The DataTransfer object stores information about the drag
operation. It can hold text data, URLs, HTML snippets, files, and
drag-effect settings.
| Property / Method | Purpose | Example Syntax |
setData() | Stores drag data. | event.dataTransfer.setData("text/plain", value) |
getData() | Reads dropped data. | event.dataTransfer.getData("text/plain") |
clearData() | Clears stored drag data. | event.dataTransfer.clearData() |
files | Gets dropped files. | event.dataTransfer.files |
items | Gets transferred items. | event.dataTransfer.items |
effectAllowed | Defines allowed drag operation. | event.dataTransfer.effectAllowed = "move" |
dropEffect | Defines drop behavior. | event.dataTransfer.dropEffect = "copy" |
setDragImage() | Sets a custom drag preview image. | event.dataTransfer.setDragImage(image, x, y) |
Drag and Drop File Upload Example
<div id="fileDropZone">
Drop files here
</div>
<ul id="fileList"></ul>
<script>
const fileDropZone =
document.querySelector("#fileDropZone");
const fileList =
document.querySelector("#fileList");
fileDropZone.addEventListener("dragover", (event) => {
event.preventDefault();
fileDropZone.classList.add("is-dragging");
});
fileDropZone.addEventListener("dragleave", () => {
fileDropZone.classList.remove("is-dragging");
});
fileDropZone.addEventListener("drop", (event) => {
event.preventDefault();
fileDropZone.classList.remove("is-dragging");
const files =
Array.from(event.dataTransfer.files);
files.forEach((file) => {
const item = document.createElement("li");
item.textContent =
file.name + " - " + file.size + " bytes";
fileList.appendChild(item);
});
});
</script>
This example allows users to drop files into a drop zone and lists the
file names and sizes. Real applications should validate file type and size
before uploading.
Sortable List Example
<ul id="todoList">
<li draggable="true">Learn HTML5</li>
<li draggable="true">Practice CSS</li>
<li draggable="true">Build JavaScript Apps</li>
</ul>
<script>
const todoList =
document.querySelector("#todoList");
let draggedItem = null;
todoList.addEventListener("dragstart", (event) => {
draggedItem = event.target;
event.target.classList.add("is-dragging");
});
todoList.addEventListener("dragend", (event) => {
event.target.classList.remove("is-dragging");
draggedItem = null;
});
todoList.addEventListener("dragover", (event) => {
event.preventDefault();
const target = event.target;
if (
target.tagName === "LI" &&
target !== draggedItem
) {
todoList.insertBefore(draggedItem, target);
}
});
</script>
This example creates a simple sortable list. For production use, include
keyboard reordering controls so users who cannot drag with a mouse can
still reorder items.
Custom Drag Preview Example
// Custom drag image
const item = document.querySelector("#card");
const preview = document.querySelector("#dragPreview");
item.addEventListener("dragstart", (event) => {
event.dataTransfer.setDragImage(
preview,
20,
20
);
event.dataTransfer.effectAllowed = "move";
});
The setDragImage() method lets you customize the preview
image shown while dragging. This improves the visual experience for drag
interactions.
Drag Effects
Drag effects describe what kind of operation is allowed during drag and
drop, such as copying, moving, or linking data.
| Effect | Description | Example Use |
copy | Creates a copy of the dragged data. | Copy file into upload area. |
move | Moves the dragged item to a new location. | Reorder cards or tasks. |
link | Creates a link to the dragged data. | Drag URL into editor. |
none | No drop operation is allowed. | Invalid drop target. |
Drag and Drop API Use Cases
| Use Case | How Drag and Drop Helps |
| File Uploads | Users can drop files directly into an upload area. |
| Kanban Boards | Move tasks between columns such as To Do, In Progress, and Done. |
| Sortable Lists | Reorder menu items, tasks, cards, or rows. |
| Image Galleries | Rearrange images or drop images for preview. |
| Page Builders | Drag components into layout areas. |
| Dashboards | Rearrange widgets and panels. |
| Editors | Drop text, links, images, or files into editable areas. |
| Shopping Carts | Drag products into a cart area. |
Drag and Drop Accessibility
Drag-and-drop interactions can be difficult for keyboard users, screen
reader users, and users with motor disabilities. Always provide an
accessible alternative for important actions.
- Provide keyboard controls for moving items up, down, left, or right.
- Use buttons such as
Move Up and Move Down for sortable lists. - Announce changes using an ARIA live region.
- Do not rely only on mouse dragging for required tasks.
- Provide visible focus styles for draggable controls.
- Use clear instructions before the drag-and-drop area.
Drag and Drop Best Practices
- Call
event.preventDefault() inside dragover to allow dropping. - Use
dataTransfer to store and retrieve drag data. - Validate dropped files before uploading.
- Provide visual feedback for valid and invalid drop zones.
- Clean up styles in
dragend, dragleave, and drop. - Keep drag payloads small and avoid exposing sensitive data.
- Support keyboard alternatives for important drag actions.
- Test drag-and-drop behavior on desktop and mobile browsers.
Common Drag and Drop Mistakes
- Forgetting
event.preventDefault() in the dragover event. - Not setting
draggable="true" on draggable elements. - Assuming drag-and-drop works the same on all mobile browsers.
- Using drag-and-drop as the only way to complete a required action.
- Not validating dropped file type or size.
- Leaving drag highlight styles after the drag operation ends.
- Sending sensitive information through
dataTransfer. - Not providing accessible instructions or keyboard alternatives.
Key Takeaways
- The Drag and Drop API enables native drag interactions in the browser.
- Use
draggable="true" to make elements draggable. - Use
dataTransfer to store and retrieve drag data. - Use
dragover with preventDefault() to allow drops. - Drag and Drop is useful for uploads, sortable lists, kanban boards, and builders.
- Always provide keyboard-accessible alternatives for important drag actions.
Pro Tip
For production applications, combine drag-and-drop with keyboard controls,
ARIA live announcements, file validation, visual feedback, and clear
instructions. This creates a drag experience that is both powerful and
accessible.