Having been a part of the Windows desktop for years, it was only a matter a time before Drag & Drop capability would come to browsers. In fact, Microsoft incorporated drag and drop into Internet Explorer 5.0 way back in 1999! With the emergence of Dynamic HTML, other browsers could also implement Drag & Drop. However, it required a lot of scripting to get it to work right. Now, HTML5’s native Drag & Drop capabilities promise to make our lives just a little bit easier.

A Work in Progress

Not to be a “Debbie Downer”, but at this early stage, HTML5’s Drag and Drop API is far from perfect. The way it’s supposed to work with all things HTML5 is that you include the feature for browsers that support it and those who don’t just have to do with a less rich experience. As nice as that would be, there is just too much of a disconnect between Internet Explorer and the DOM-compliant browser objects and document structure for such a dream to come to fruition. Even within the realm of the standards-compliant players, Opera, Firefox, Safari, and Chrome, there are many quirks and inconsistencies to negotiate. Nonetheless, the new HTML5 API is enough of a step forward over existing script-based ones to start using it.

Browser Support

HTML5 Drag & Drop is supported in Firefox 3.5+, Chrome 3.0+, Safari 3.0+. Opera support should follow soon enough. Support in Internet Explorer is not as cut and dry. Although it was the pioneer of Drag & Drop, Internet Explorer has supported draggging of images, links, and text since version 5.0. However, it wasn’t until version 10 that support for the draggable attribute was added. Version 10 goes a step further and provides the ability to drag files from the desktop to a webpage–a great compliment to the JS FileReader API.

Defining an Element as “Draggable”

By default, both images and link elements are draggable without any additional coding. If you want to drag a different element, you need to add a special attribute. In DOM-compliant browsers, a draggable node requires a “draggable” attribute which is set to “true”. As mentioned earlier, Internet Explorer is limited to images and links below version 10, since earlier versions don’t support the draggable attribute.
n the following example, the link element is draggable in all of the browsers mentioned above even without the draggable attribute. The <span> element is not draggable in Internet Explorer 9 or below:
<a href="#" id="toDrag">This is a draggable item</a>
<span draggable="true">This item is not draggable in IE 9!</span>
The following HTML markup contains a draggable link and image as well as <div> that will act as a drop area. Believe it or not, we’re already half done even though we haven’t written any scripting code!
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta charset=utf-8 />
<title>A Basic Drag & Drop Demo</title>
<style>
#drop {
  min-height: 150px;
  width: 250px;
  border: 1px solid blue;
  margin: 10px;
  padding: 10px;
}
</style>
</head>
<body>
  <h1 align=center>A Basic Drag & Drop Demo</h1>
  <a href="http://www.robgravelle.com" id="text" draggable="true">This is a draggable item</a>
  <img id="ball" alt="ball (2K)" src="ball.gif" height="50" width="50" />
  <div id="drop"></div>
</body>
</html>

The JavaScript Code

Oddly enough, the way to tell the browser that an element can act as a drop zone is to cancel its dragover() and dragenter() events. The former is for DOM-compliant browsers while the latter applies to Internet Explorer.
Here then is the code to set up the drop as a dropoff point:
  var drop = document.getElementById('drop');

  function cancel(e) {
    if (e.preventDefault) e.preventDefault();
    return false;
  }

  //Tells the browser that we can drop on this target
  addEvent(drop, 'dragover', cancel);  //DOM event
  addEvent(drop, 'dragenter', cancel); //IE event
You’re probably unfamiliar with the addEvent() function. It’s part of the h5utils.js JavaScript library and is a browser agnostic method for adding event listeners. You can download the file via the “View raw file” link on the right-hand side of the page to include it in your own scripts. For your own edification, here is the addEvent() function code:
var addEvent = (function () {
  if (document.addEventListener) {
    return function (el, type, fn) {
      if (el && el.nodeName || el === window) {
        el.addEventListener(type, fn, false);
      } else if (el && el.length) {
        for (var i = 0; i < el.length; i++) {
          addEvent(el[i], type, fn);
        }
      }
    };
  } else {
    return function (el, type, fn) {
      if (el && el.nodeName || el === window) {
        el.attachEvent('on' + type, function () { return fn.call(el, window.event); });
      } else if (el && el.length) {
        for (var i = 0; i < el.length; i++) {
          addEvent(el[i], type, fn);
        }
      }
    };
  }
})();

Coding the Drop Event

To respond to the drop event, all you have to do is add an event handler to it as follows:
  addEvent(drop, 'drop', function (e) {
    if (e.preventDefault) e.preventDefault(); // stops the browser from redirecting off to the text.
    this.innerHTML = "<strong>Done!</strong>";
    this.style.backgroundColor="#CCCC00";

    return false;
  });
</script>
The above code presents a message in the drop element and changes the background color. Notice that we have to call the Event.preventDefault() method and return “false” because the browser will automatically treat the object as a link and attempt to redirect otherwise. If we were to remove that line, the ball image would be presented in a new page and draggable text would forward to the page contained in the link’s HREF attribute. That can be a desirable consequence in some instances so it’s good to know how to toggle the redirecting behavior on and off.

Conclusion

Today we explored the basics of the HTML5 Drag & Drop API. Next time, we’ll learn how the dataTransfer property can be used to shuttle data and document elements from one part of the page to another.