Html 5 Drag & Drop

Introduction

HTML5 now defines a direct API for handling drag and drop (“D&D”). This API allows us to specify that certain elements are draggable, and then specify what should happen when these draggable elements are dragged over or dropped onto other elements on the page.

Browser support for Drag and Drop

Drag and Drop is supported in:

  • Safari 3.2+
  • Chrome 6.0+
  • Firefox 3.5+ (there is an older API that was supported in Firefox 3.0)
  • Internet Explorer 7.0+
  • Android 2.1+
--

Checking for Support with User's browser

To test if the browser supports native D&D functionality, use the following feature detect.

var dnd_support = 'draggable' in document.createElement('span');

Making Elements Draggable

HTML5 spec added some new content to the API. Enabling any element to be dragged is incredibly easy. Take your div and add the new attribute: draggable.

<div draggable="true">This element be draggable</div>

The DataTransfer Object

DataTransfer objects are one of the new objects outlined in the Drag and Drop API. These objects allow us to set and get data about the objects that are being dragged

DataTransfer lets us define two pieces of information.

  1. the type of data we’re saving about the draggable element
  2. the value of the data itself

By using the setData and getData methods on the dataTransfer object, you can pass data from elements inside our application to other pages of our app, or across browser windows

Dragging data to other applications
snippet
img.ondragstart = function(event) {
    event = event || window.event;
    // here be one long line
    event.dataTransfer.setData('text / plain', 'This is the screen name
        for' +this.getAttribute('data - screen_name') + ', whose image can be found here: '+this.src);
};
--

Drag and Drop Events

In total, there are seven drag and drop events.

PropertiesDescription
dragenter
dragoverTell the browser this is an element that accepts drop data.
dropOnce something has been dropped on the element, do something with the dropped data.
dragstart
dragend(the complement to dragstart)
dragenter
dragleave

The enter and leave events fire on the dropzone as the dragged item enters the element.

--

Creating a D&D Application

Simple D&D demo.

snippet
<style>
#foobar { background-color:yellow; width:100px; height:100px; cursor:move; }
#catcher { background-color:blue; width:150px; height:150px; padding:5px; margin-bottom:5px; }
</style>

Enable D&D:-

Put the draggable attribute on the element you want to be drag-enabled:

snippet
<div id="catcher">...</div>
<div id="foobar" draggable="true">...</div>

We need to use the JavaScript API and D&D events to tell the browser where the element can be dragged to, and what to do once it's dropped there.

For example, we can listen for the dragstart event, and style the element differently when it's being dragged (like putting a border around it or making it partially transparent).

snippet
var foobar = document.getElementById("foobar");
foobar.addEventListener("dragstart", function(evt) {
    this.style.border = "3px dotted #000"; // black dotted-line border
}, false);

Lets style an element that can receive the drop, so that when the dragged item is over it, it makes it obvious that you can drop the element there (as opposed to just dropping it in any location):

snippet
var catcher = document.getElementById("catcher"); // will catch the dropped element
catcher.addEventListener("dragenter", function(evt) {
    this.style.border = "3px solid red"; // make the catcher have a red border
}, false);
catcher.addEventListener("dragleave", function(evt) {
    this.style.border = ""; // remove the border from the catcher
}, false);
catcher.addEventListener("dragover", function(evt) {
    if (evt.preventDefault) evt.preventDefault();
    return false;
}, false);

Add event listeners to the element that catch our dropped element for the dragover, dragenter, and dragleave events.

dragenter and dragleave - events simply toggle on a red border to our target element to make it clear that you can drop the element there.

dragover - event is fired continuously while dragging around on top of the target.

So we would not want to toggle on the red border in that handler, as that would create unnecessary work for the browser. However, we do need to prevent that event from various default behavior, depending on the type of element being dragged. This is why we use preventDefault() and return false.

Modify our dragstart event handler to wire up a dataTransfer object with data that the browser needs for handling the D&D actions

snippet
foobar.addEventListener("dragstart", function(evt) {
    this.style.border = "3px dotted #000"; // black dotted-line border
    evt.dataTransfer.effectAllowed = "move";
    evt.dataTransfer.setData("Text", this.id);
}, false);

effectAllowed property - controls what visual feedback—generally the mouse cursor—the browser gives on the type of drag event that is occurring (move, copy, etc.).

setData(...) - method tells the D&D mechanism in the browser which data from the element being dragged should be dropped into the target element, otherwise known as the drop catcher. Here we specify that only the id property of the original element is transferred, which is used later to actually move the element.

Define a dragend event handler to clear up the visuals, and a drop event handler, to actually do the moving of our element:

snippet
foobar.addEventListener("dragend", function(evt) {
    this.style.border = ""; // remove the border
}, false);
catcher.addEventListener("drop", function(evt) {
    if (evt.preventDefault) evt.preventDefault();
    if (evt.stopPropagation) evt.stopPropagation();
    this.style.border = ""; // remove the border from the catcher
    var id = evt.dataTransfer.getData("Text"); // get the id
    var elem = document.getElementById(id);
    elem.parentNode.removeChild(elem); // remove the element
    this.appendChild(elem); // add the element back into our catcher
    return false;
}, false);

The drop event handler, we first get the data that was transferred in the drop, which in this case was the id property of the original source element that we dragged. Next, we remove that element from its current location, and finally add it back into the new location inside our catcher container.

Related Tutorial
Follow Us
https://www.facebook.com/Rookie-Nerd-638990322793530 https://twitter.com/RookieNerdTutor https://plus.google.com/b/117136517396468545840 #
Contents +