Skip to content

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.