HTML5 Tutorial – Drag and Drop

imageDrag and drop is a part of the HTML5 standard. Drag-and-drop functionality is something that computer users have come to take for granted as “just working,” and there are a few ways to enable it within the browser.

Imagine a computer or smartphone with a pointing device. — a drag operation could be like a mousedown event that is followed by a series of mousemover events, and the drop could be triggered by the mouse being released.

Drag-and-drop operations:

  • Drag Source. Must have a starting point (e.g. where the mouse was clicked, or the start of the selection or element that was selected for the drag),.
  • May have any number of intermediate steps (elements that the mouse moves over during a drag, or elements that the user picks as possible drop points as he cycles through possibilities).
  • Drop Target. Must either have an end point (the element above which the mouse button was released, or the element that was finally selected), or be canceled. The end point must be the last element selected as a possible drop point before the drop occurs (so if the operation is not canceled, there must be at least one element in the middle step).

During the drag and drop, the browsers will send you lots of events over the course of the drag. You will have the power to change the DOM and the style of the page elements in response to the user actions.

In most browsers, text selections, img elements, and anchor elements with an href attribute are draggable by default.

Data Transfer

You also get a set of objects to help transfer data from the drag source to the drop target. You can think of data transfer objects as a central control for drag-and-drop. The operation type, the image to use as feedback during the drag, and the retrieval of the data are all managed in the data transfer objects.

Data transfer works in a similar way to a network protocol negotiation. In this case, the negotiation is performed via MIME types. The MIME types are the same as used to attach files to an email.

Browser Support

Drag and drop as specified in HTML5 is supported in IE10, Windows Store apps, Firefox 18+, Chrome 24+, Safari 5.1+, and Opera 12.1+. It is not currently supported on most Smartphone browsers. You can see the latest in Can I use Drag and Drop.

Feature Detection

You can use Modernizr to detect the drag and drop feature.


if (Modernizr.draganddrop) {
// Browser supports HTML5 DnD.
} else {
// Fallback to a library solution.
}

Getting Started with Drag and Drop

There are four steps in getting an object to drag and drop. You will need:

  • Draggable Elements. Make an element draggable.
  • Drag Event. Specify what should happen when the element is dragged.
  • Drag Over. Specify where the dragged data can be dropped.
  • Drop. When the dragged data is dropped, specify what should happen.

Let’s look at the code and then dive into the code to see how it works:

<


<!DOCTYPE HTML>
<html>
<head>
<title>Drag Logo</title>
<style type="text/css">
#dropOnMe {
width: 210px;
height: 136px;
padding: 10px;
border: 1px solid #aaaaaa;
}
</style>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("Id", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("Id");
ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>
<p draggable="false">Drag the image into the rectangle:</p>
<div id="dropOnMe" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="dragImage" src="images/nextechpress.png" draggable="true"
ondragstart="drag(event)">
</body>
</html>

Draggable Elements

To make an element draggable, set the draggable attribute to true. In the following example, an image is made draggable.

<img id="dragImage" src="images/nextechpress.png" draggable="true" 
    ondragstart="drag(event)">

The draggable attribute allows you to make any HTML element able to be dragged on the page. It provides the following states.

  • true. The content can be dragged.
  • false. The content cannot be dragged.
  • auto. The content takes the default browser behavior (text, links, and images are draggable; other elements are not.)

We do not handle the data that would be coming in from the initial paragraph, which by default the user could drag, you set the draggable attribute to false.

<p draggable="false">Drag the image into the rectangle:</p>

The browser provides a ghost image that moves with the cursor as it’s dragged. This image may be customized; however, most of the time, you would not specify this, and a default image will be generated based on the element where the mouse was pressed down.

The draggable attribute is not inherited, so children of an element are not automatically draggable.

Drag Event

Next, you specify what should happen when you begin dragging an element.

You connect up the image with the ondragstart attribute that cause the drag function to be called.

<img id="dragImage" src="images/nextechpress.png" draggable="true" 
    ondragstart="drag(event)">

Inside the drag() function, we set the data that we’re transferring. In this case, it is the identifier of the element that we are moving. And the identifier is text.

function drag(ev) {
    ev.dataTransfer.setData("Text", ev.target.id);
}

DragOver Event

The dragover event occurs as the mouse moves over an element during the drag operation. So the drop location responds.

<div id="dropOnMe" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

To compare

  • The drag event is called on the drag source.
  • The dragover event is called on the current target of the mouse. This is where you can have elements respond, such as change color, before the item being dragged is dropped.

In our case, we want stop further propagation of the event..

function allowDrop(ev) {
    ev.preventDefault();
}

Drop Event

The drop event occurs on the element where the drop was occured at the end of the drag operation. A listener would be responsible for retrieving the data being dragged and inserting it at the drop location. This event will only fire if a drop is desired. It will not fire if the user cancelled the drag operation, for example by pressing the Escape key, or if the mouse button was released while the mouse was not over a valid drop target.

The drop event is put into our drop location.

<div id="dropOnMe" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

And the drop event stops further propogation of the event, and then gets the data from the data transfer object and does something with it.

function drop(ev) {
    ev.preventDefault();
    var data = ev.dataTransfer.getData("Id");
    ev.target.appendChild(document.getElementById(data));
}

Best Practices

It is the negotiation process that allows the drag sources and drag targets to be decoupled. As long as the data sources provide data in a choice of MIME types, the drop target can choose which formats to accept, even if they come from two different developers.

Drag and Drop Events

A number of events are used which are fired during various stages of the drag and drop operation. Note that only drag events occur – mouse events such as mousemove do not occur during the drag.

  • dragstart occurs on an element when a drag is started. The user is requesting to drag the element the dragstart event occurs.
  • dragenter occurs when the mouse is first moved over an element during a drag. A listener for this event should indicate whether a drop is allowed over this location. If there are no listeners, or the listeners perform no operations, then a drop is not allowed by default. This is also the event to listen to if you want to provide feedback that a drop is allowed such as displaying a highlight or insertion marker.
  • dragover occurs as the mouse is moved over an element during a drag. Much of the time, the operation that occurs during a listener will be the same as the dragenter event.
  • dragleave occurs when the mouse leaves an element during the drag. Listeners should remove any highlighting or insertion markers used for drop feedback.
  • drag occurs at the source of the drag, that is, the element where dragstart was fired, during the drag operation.
  • drop occurs on the element at the end of the drag operation. A listener would be responsible for retrieving the data being dragged and inserting it at the drop location. This event will only fire if a drop is desired.
  • dragend. The source of the drag will receive a dragend event when the drag operation is complete, whether it was successful or not.

DataTransfer Object

The DataTransfer object is used to hold the data that is being dragged during a drag and drop operation.

DataTransfer is set using:

e.dataTransfer.setData(format, data);

and retrieved using:

var myData = e.dataTransfer.getData(format);

IE10 supports two kinds of DataTransfer format types.

  • Text. For data formatted as text.
  • URL. For data formatted as a URL.

You can also drag and drop files in the next posting.

Resources

Sample Code

Sample code is available in the DevDays GitHub repository. See https://github.com/devdays/html5-tutorials