HTML5 LogoWhile there are plenty of JavaScript libraries that take the pain out of drag-and-drop, understanding how to implement this feature of HTML5 is not only possible, it’s easier than you may think.

So let’s face facts: drag and drop is something that most of us take for granted. Ever since the late ‘80s, we’ve been able to drag something on the screen and then drop it somewhere as a way of saying: “I want this.” or “ ….do something to this.” In recent years, that kind of functionality has become more and more commonplace in desktop browsers. It’s hard to believe, but drag-and-drop was originally supported in Microsoft Internet Explorer 5. Yep, the XMLHttpRequest object is not the only game-changing feature originally dreamed-up at Microsoft. Ironically, our good friend IE is the only major browser whose support is limited. IE 10 seems to be fairly in line with regard to the most critical features, but IE 9 and below lack features that make native drag and drop implementation frustrating.

Let’s close our eyes for a moment, and pretend we don’t need to support Microsoft Internet Explorer

Fortunately, the HTML5 specification includes a fairly robust API for drag and drop. Making HTML elements draggable and droppable is painless, and managing the related events is possible. The key to all of this is understanding the bare minimum needed in order to properly manage this functionality.

But isn’t everything “draggable” these days?

No, not quite. According to the HTML5 Drag and Drop specification, only images and anchor links are draggable by default (and the anchor must have an href attribute). So, if you want to drag any other kind of HTML element, there is a bit of work to do.

Wait, aren’t there a gazillion JavaScript libraries that make drag and drop a snap?

Yep, there sure are. So, if you merely want to download a library or jQuery plugin and simply “dragify” as needed, this article probably isn’t for you. But if you want to understand how native HTML5 drag and drop functionality works, read on!

HTML Base

In the code example above, we have the base HTML for the rest of the examples in this article. For brevity sake, I’ve stripped out all but the most essential areas of the markup so that you can focus on the technologies demonstrated in this article. When you view the page source for the final working example, you will see that there is more HTML, but it is for presentational purposes only.

Making an Element Draggable

In order to make an element draggable, you need only add a “draggable” attribute to that element, and set its value to “true”. This can be done by including the “draggable” attribute in the original html, or via JavaScript.

Example # 1A

In Example # 1A, we have made an HTML draggable by adding a “draggable” attribute to that element, and setting its value to “true”. While I could have simply added a “draggable” attribute to the HTML, I chose to do so using JavaScript in order to illustrate how much control you have over this.

The dragstart Event

While the code in Example # 1A is completely valid, unless the element in question is an image, or an anchor tag (with an href attribute), there is a bit more work to do. Providing a “draggable” attribute alone is not enough to make an element draggable. There is at minimum, a second step: provide an event handler for the dragstart Event.

The dataTransfer Object

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

Even in the most basic drag and drop implementation, the dataTransfer object is important. The reason for this is the core logic behind drag and drop: why would you want to drag something if you did not plan to eventually drop it? (At first I found this frustrating; I felt that the “draggable” attribute alone should suffice when you want to be able to drag an element. But the more I delved into the specification, the more the logic started to make sense.)

In order to drag an element, you’ll need to provide some data to the dataTransfer object. Ultimately, it does not matter what data you provide; you just need to use the setData method of the dataTransfer object to set some data. You must do this in the dragstart event. After your dragstart event handler returns, you cannot modify the dataTransfer object.

I bet I know what you are thinking now:

Aaaaaaaaaaaaahhhhhh, c’mon Kevin, another friggin’ object I gotta learn about? In the Intro you said something about this whole thing being “…easier than you may think” !!

I know. I kinda lied. But aren’t you glad you’re halfway across the river?

(Seriously, this is all no big deal. Considering how cool drag and drop is, learning about a few objects and methods is a small price to pay.)

The originalEvent Object

When thinking about drag and drop events, it becomes necessary to consider multiple event objects. For example, when you start dragging an element, it fires a “dragStart” event. But then consider the element that you might drop this element on. It fires a number of events as well. When handling any of these events, you will need access to the original event that fired, as a way to refer to the HTML element that was dragged. So, in your dragstart event handler, you’ll want to create a reference to the dragged HTML element itself. This way, in any of the events fired by the droppable element, you can obtain a reference to the element that was dragged (i.e. the element that you might want to drop onto the droppable element).

Example # 1B

In Example # 1B, we bind an event handler for the dragstart event of the HTML element that we plan to drag. That handler is the function: dragStartHandler. The dragStartHandler function takes the current event as its first argument. We then use the setData method of the originalEvent’s dataTransfer object. The originalEvent object is a property of the current event. In this case, the originalEvent is the dragStart event. When calling the setData method, we pass “Text” as the first argument. That simply tells the setData method what type of data we are about to set. The second argument is the ID attribute of the element that is being dragged. This is accomplished by referencing the target object of the event, which is the element that is being dragged, and then use the target object’s getAttribute method to retrieve the ID attribute of the target element.

Setting Up the Droppable Element

You don’t need to do anything special to allow one HTML element to be dragged over another. Once an element is properly “draggable,” you can drag it anywhere you like. But just like playing cards with Kenny Rogers, that gets old pretty quick. The next logical step in implementing HTML5 drag and drop is setting up the droppable element(s) so that you can handle the various events that fire during the process.

The dragover and drop Events

Example # 2

The dragover Event

In Example # 2, we have bound two event handlers to the droppable HTML element. The allowDragover function is bound to that element’s dragover event, and as you can see, it has little functionality: it simply prevents any default behavior that the browser might implement. Surprisingly, this is critical; the drop functionality will not work correctly without it. This is one event handler that you have to simply “set and forget.”

The drop Event

In Example # 2, we bind the dropHandler function to the drop event of the droppable element. This is where the real action should take place.

Example # 3

In Example # 3, we’ve added some functionality to the dropHandler function. First, we prevent any default behavior that the browser might have implemented. Next, we retrieve the ID of the HTML element that was dragged, leveraging the work that we did in the dragStartHandler function. The steps here are virtually the opposite of those taken to set the ID of the dragged element: we use the getData method of the originalEvent’s dataTransfer object, which itself is a property of the event object’s originalEvent property.

Next, we add the class “hasChild” to the element that received the drop. This is for presentational purposes only, but it does allow us to provide a better user experience by changing the appearance of the element that received the drop. Then we “move” the element simply by appending it to the droppable element, and then change the dragged element’s innerHTML to “Dropped”. Just like changing the appearance of the droppable element, this kind of approach usually makes for a better user experience.

Example # 4

In Example # 4, we have the full code for our working example.

Here is the working example for this article: http://examples.kevinchisholm.com/html5/drag-and-drop/part-i.html

Here is the JavaScript for this article’s working example: http://examples.kevinchisholm.com/html5/drag-and-drop/js/part-i.js

Summary

This article barely scratches the surface of what is possible with HTML5 Drag and Drop. My goal was to provide an introduction to the topic that focused on the bare essentials needed to get started. Below are links that provide much more in-depth information on the subject.

Helpful Links for HTML5 Drag and Drop

http://www.w3.org/TR/2011/WD-html5-20110113/dnd.html

http://html5demos.com/drag

http://www.webdesignerdepot.com/2013/08/how-to-use-html5s-drag-and-drop/

https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer

https://developer.mozilla.org/en-US/docs/Web/Events/dragstart

http://tutorials.jenkov.com/html5/drag-and-drop.html