Skip to content

HTML5 Drag and Drop

Drag and Drop is a very intuitive and powerful feature in HTML5. It allows users to select a draggable element with the mouse, "drag" it to a specified "drop zone," and "drop" it.

Making an Element Draggable

To make an element draggable, you need to set its draggable attribute to true.

html
<img src="logo.png" draggable="true">

By default, only links and images are draggable. For other elements like <div> or <p>, you must explicitly set draggable="true".

Drag and Drop Event Cycle

The entire drag and drop process consists of a series of events that we can listen to for controlling drag and drop behavior.

Events on the Dragged Element

  • ondragstart: Triggered when the user starts dragging an element. This is the starting point of the whole process.
  • ondrag: Continuously triggered while the element is being dragged.
  • ondragend: Triggered when the user completes dragging (whether successful drop or cancelled).

Events on the Drop Zone

  • ondragenter: Triggered when the dragged element enters the drop zone.
  • ondragover: Continuously triggered while the dragged element moves over the drop zone.
  • ondragleave: Triggered when the dragged element leaves the drop zone.
  • ondrop: Triggered when the dragged element is released over the drop zone. This is the core of the drop operation.

A Complete Drag and Drop Example

Let's look at a complete example of dragging an image into a <div> container.

HTML:

html
<div id="drop-zone" ondrop="drop(event)" ondragover="allowDrop(event)">
  <p>Drag the image here</p>
</div>
<br>
<img id="drag-item" src="logo.png" draggable="true" ondragstart="drag(event)" width="150">

CSS (for visual feedback):

css
#drop-zone {
  width: 200px;
  height: 100px;
  padding: 10px;
  border: 2px dashed #aaaaaa;
}

JavaScript:

javascript
// 1. ondragover: Must prevent default behavior
function allowDrop(ev) {
  // By default, elements cannot be dropped onto other elements.
  // To allow dropping, we must prevent the browser's default handling.
  ev.preventDefault();
}

// 2. ondragstart: Record the dragged data
function drag(ev) {
  // dataTransfer.setData() method sets the dragged data's type and value.
  // Here, we save the dragged element's id ('drag-item').
  ev.dataTransfer.setData("text", ev.target.id);
}

// 3. ondrop: Perform the drop operation
function drop(ev) {
  // Also prevent the browser's default behavior (e.g., images default to opening in a new tab).
  ev.preventDefault();

  // Use dataTransfer.getData() to retrieve the data saved in the drag() function.
  var data = ev.dataTransfer.getData("text");

  // Get the dragged element (id='drag-item').
  var draggedElement = document.getElementById(data);

  // Append the dragged element to the drop zone.
  ev.target.appendChild(draggedElement);
}

Code Analysis

  1. allowDrop(event): This is the most easily overlooked but crucial step. By default, browsers prevent drop operations on elements. By calling event.preventDefault(), we tell the browser: "This area is a valid drop target."
  2. drag(event): When dragging starts, we need a way to "remember" which element we're dragging. event.dataTransfer.setData("text", event.target.id) does exactly this. It stores the dragged element's id as text in the dataTransfer object.
  3. drop(event): When the element is dropped, we first use event.dataTransfer.getData("text") to retrieve the previously stored id, then use document.getElementById() to find this element, and finally use appendChild() to move it to the drop zone.

Content is for learning and research only.