Clean • Professional
The Drag and Drop API allows users to drag elements (like images, files, or text) and drop them into another area on the page. It makes web apps more interactive.
Key Features:
draggable="true".draggable="true" to make an element draggable.dragstart, drag, dragend.dragenter, dragover, dragleave, drop.event.preventDefault() in dragover to allow dropping.event.dataTransfer to pass information (e.g., the dragged element’s ID or file data).draggable attribute: enables dragging on an element.<div draggable="true">Drag me</div>dragstart: set data with dataTransfer.setData(...)dragover: call preventDefault() to enable dropdrop: read data with dataTransfer.getData(...)dataTransfer object
setData(type, data) / getData(type)files (when dragging files from desktop)setDragImage(img, x, y) to customize the drag ghost imageExample 1: Basic Drag a Box into a Drop Zone
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Drag Box</title>
<style>
#box {
width: 80px; height: 80px;
background: tomato;
margin: 20px; cursor: grab;
}
#dropZone {
width: 200px; height: 150px;
border: 2px dashed #666;
text-align: center; padding-top: 50px;
}
</style>
</head>
<body>
<h3>Drag the box into the drop zone</h3>
<div id="box" draggable="true"></div>
<div id="dropZone">Drop here</div>
<script>
const box = document.getElementById("box");
const dropZone = document.getElementById("dropZone");
box.addEventListener("dragstart", (e) => {
e.dataTransfer.setData("text/plain", "box");
});
dropZone.addEventListener("dragover", (e) => e.preventDefault());
dropZone.addEventListener("drop", (e) => {
e.preventDefault();
dropZone.textContent = "Box Dropped!";
});
</script>
</body>
</html>
Output :

Example 2: Drag-and-Drop File Upload (Preview Images)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>File Upload</title>
<style>
#fileZone {
width: 300px; height: 150px;
border: 2px dashed #666;
text-align: center; padding-top: 50px;
margin-bottom: 10px;
}
#preview img { max-width: 100px; margin: 5px; }
</style>
</head>
<body>
<h3>Drag and drop images</h3>
<div id="fileZone">Drop images here</div>
<div id="preview"></div>
<script>
const fileZone = document.getElementById("fileZone");
const preview = document.getElementById("preview");
fileZone.addEventListener("dragover", (e) => e.preventDefault());
fileZone.addEventListener("drop", (e) => {
e.preventDefault();
const files = e.dataTransfer.files;
for (let file of files) {
if (file.type.startsWith("image/")) {
const reader = new FileReader();
reader.onload = (event) => {
const img = document.createElement("img");
img.src = event.target.result;
preview.appendChild(img);
};
reader.readAsDataURL(file);
}
}
});
</script>
</body>
</html>
Output :

Example 3: Custom Drag Image (Ghost)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Custom Drag Image</title>
<style>
#dragMe {
width: 100px; height: 100px;
background: teal; color: white;
text-align: center; line-height: 100px;
cursor: grab;
}
#dropTarget {
margin-top: 20px;
width: 250px; height: 120px;
border: 2px dashed gray;
text-align: center; padding-top: 40px;
}
</style>
</head>
<body>
<h3>Custom ghost image while dragging</h3>
<div id="dragMe" draggable="true">Drag me</div>
<div id="dropTarget">Drop here</div>
<script>
const dragMe = document.getElementById("dragMe");
const dropTarget = document.getElementById("dropTarget");
dragMe.addEventListener("dragstart", (e) => {
const ghost = document.createElement("div");
ghost.style.width = "80px";
ghost.style.height = "80px";
ghost.style.background = "orange";
ghost.style.borderRadius = "50%";
document.body.appendChild(ghost);
e.dataTransfer.setDragImage(ghost, 40, 40);
setTimeout(() => ghost.remove(), 0);
});
dropTarget.addEventListener("dragover", (e) => e.preventDefault());
dropTarget.addEventListener("drop", (e) => {
e.preventDefault();
dropTarget.textContent = "Dropped with custom ghost!";
});
</script>
</body>
</html>
Output :

Example 4: Sortable List (Reorder Items)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sortable List</title>
<style>
ul { list-style: none; padding: 0; }
li {
padding: 10px; margin: 5px;
background: lightblue;
cursor: move;
}
</style>
</head>
<body>
<h3>Reorder the items by dragging</h3>
<ul id="sortable">
<li draggable="true">Item 1</li>
<li draggable="true">Item 2</li>
<li draggable="true">Item 3</li>
<li draggable="true">Item 4</li>
</ul>
<script>
const sortable = document.getElementById("sortable");
let draggedItem = null;
sortable.addEventListener("dragstart", (e) => {
draggedItem = e.target;
});
sortable.addEventListener("dragover", (e) => {
e.preventDefault();
const target = e.target;
if (target.tagName === "LI" && target !== draggedItem) {
const rect = target.getBoundingClientRect();
const next = (e.clientY - rect.top) / (rect.height) > 0.5;
sortable.insertBefore(draggedItem, next ? target.nextSibling : target);
}
});
</script>
</body>
</html>

dataTransfer.files.