The Codex / JavaScript / Drag & Drop

Drag & Drop

Native HTML5 drag and drop — draggable elements, drop targets, DataTransfer, file drops, and sorting lists.

What it is, in plain English: The HTML5 Drag and Drop API lets users drag elements around the page and drop them on designated targets. The dragging element fires dragstart, drag, and dragend events. The drop target fires dragenter, dragover, dragleave, and drop events. DataTransfer carries the data from drag source to drop target. File drops (from the OS) use the same API — files arrive in event.dataTransfer.files.

Making elements draggable

Basic drag and drop

<!-- HTML: add draggable="true" to make an element draggable -->
<div draggable="true" id="card">Drag me!</div>
<div id="drop-target">Drop here</div>
const card       = document.getElementById("card");
const dropTarget = document.getElementById("drop-target");

// ── DRAGGABLE ELEMENT EVENTS ──────────────────────────────────────────────
card.addEventListener("dragstart", (event) => {
  // Store data to pass to the drop target:
  event.dataTransfer.setData("text/plain", card.id);
  event.dataTransfer.effectAllowed = "move";  // "copy", "move", "link"
  card.classList.add("dragging");
});

card.addEventListener("dragend", () => {
  card.classList.remove("dragging");
});

// ── DROP TARGET EVENTS ────────────────────────────────────────────────────
dropTarget.addEventListener("dragover", (event) => {
  event.preventDefault();  // ← REQUIRED or drop won't fire!
  event.dataTransfer.dropEffect = "move";
  dropTarget.classList.add("drag-over");
});

dropTarget.addEventListener("dragleave", () => {
  dropTarget.classList.remove("drag-over");
});

dropTarget.addEventListener("drop", (event) => {
  event.preventDefault();
  const id      = event.dataTransfer.getData("text/plain");
  const dragged = document.getElementById(id);
  dropTarget.appendChild(dragged);   // move the element
  dropTarget.classList.remove("drag-over");
});

File drop — dragging files from the desktop

dropZone.addEventListener("dragover", (e) => {
  e.preventDefault();
  dropZone.classList.add("active");
});

dropZone.addEventListener("drop", (e) => {
  e.preventDefault();
  dropZone.classList.remove("active");

  // Access dropped files:
  const files = [...e.dataTransfer.files];
  files.forEach(file => {
    console.log(`File: ${file.name} (${file.type}, ${(file.size/1024).toFixed(1)}KB)`);

    if (file.type.startsWith("image/")) {
      const reader = new FileReader();
      reader.onload = (e) => { preview.src = e.target.result; };
      reader.readAsDataURL(file);
    }
  });
});
Try It Yourself

Official Sources

The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.