Skip to main content

Natural User Interaction with Drag-and-Drop

Posted by manning_pubs on October 29, 2012 at 5:44 AM PDT



Natural User Interaction with Drag-and-Drop

by Rob Crowther, author of Hello! HTML5 and CSS3

The HTML5 spec is ground-breaking in many ways, but one of the key ways is that it specifies both the syntax of the HTML markup and the APIs you should use to manipulate the document with JavaScript. In this article from Hello! HTML5 & CSS3, author Rob Crowther discusses simulating desktop-like interactions with the drag-and-drop API. Click here for 40% savings on Hello! HTML5 and CSS3 and other related titles.

Drag-and-drop is a metaphor familiar on your desktop computers&emdash;you've probably used it for sorting files into folders, adding attachments to emails, and opening a file in a particular program. It's therefore useful when writing web applications to support this drag-and-drop metaphor both within your application and as an interaction method with other content on the user's computer. This functionality is provided in HTML5 in the drag-and-drop API.

The drag-and-drop API makes use of a few properties and a lot of events. The following sequence of diagrams gives you an overview of which events fire when before we dive into code in the following section.

Now that you have an overview, let's examine the details.

Basic drag-and-drop

To make an element draggable is simple, with a couple of browser compatibility caveats that we'll get to later: add a draggable attribute with value true. This first example has a list of locations in the Columbia Internet offices that you'll make draggable:

On each of the elements, the ondragstart attribute has been set. This function is used to set the data that will be passed by the drag-and-drop action. For now, you'll set the text data as the ID of the element:

Within the function there's also a log command so the sequence of events firing is recorded on the page. As the element with ID 'support' is dragged, the messages are added at the bottom of the page.

The crucial event in the drag-and-drop process is dragOver. Any element that is to be a target for dropped elements must capture the dragOver event and cancel the default action on it:

When the element is dropped, the drop event is fired. It's in this event that the actual work needs to be done. This example removes the list item from the source list and adds it to the selected list using the standard appendChild method:

These two events can be bound declaratively to the drop target element:

If you only want drag-and-drop to work in Firefox, Chrome, and Safari, that's all the code you need&emdash;you're done! If you want it to work in IE too, read ahead to the next section.

Drag-and-drop in all browsers

Although the HTML5 drag-and-drop API is based on what IE5.5 implemented, it's not identical. What that means is that, although it's possible to write cross-browser code for drag-and-drop that works across Firefox, Chrome/Safari, and IE, doing so isn't as straightforward as the code given in the previous section.

Problem 1

The draggable attribute is an innovation of the HTML5 spec, and IE8 doesn't recognize it. By default, nothing in the previous example is draggable in IE.

Solution 1

Links are draggable by default, so by making everything that should be draggable a link, IE can be supported.

The draggable attribute is no longer required because links are draggable by default.

Problem 2

Older versions of IE use srcElement instead of target.

Solution 2

Do the standard IE support bait-and-switch.

Problem 3

The ondragover attribute doesn't work in IE8 and earlier.

Solution 3

There are two possible approaches to solving this problem. The first approach is to handle the dragenter event, which older versions of IE recognize, instead of the dragover event, which they do not.

The second (and better) approach is to attach the event handler in script rather than declaratively in the HTML markup. The advantage of this approach is that, while attaching the handler declaratively will cause the event to fire, canceling that event won't make the element a drop target in IE8 and earlier. But if you use the proprietary attach-Event() method to attach to the dragOver event in script, canceling that will make the element a drop target. Attaching the event this way is straightforward; the code is shown here:

Note that for advanced developers the best practice is to always attach event handlers in script. For now, this snippet can be copied and pasted into your own code.

Problem 4

Chrome is now broken!

Solution 4

Find the closest parent ID.

You can avoid this issue altogether if the elements you want to drag are links or images&emdash;add the ID directly to those draggable elements. An alternative approach for IE support on elements that aren't draggable by default is to add the links dynamically with script only in IE.

Summary

This article has presented one of the most interesting HTML5 APIs, focused on enriching the in-browser experience. We've covered creating word processor-style WYSIWYG editing interfaces and allowing natural drag-and-drop interactions.


Here are some other Manning titles you might be interested in:

HTML5 in Action

HTML5 in Action
Robert Crowther, Joe Lennon, Ash Blue and Greg Wanish

HTML5 for .NET Developers

HTML5 for .NET Developers
Jim Jackson II and Ian Gilman

Sass and Compass in Action

Sass and Compass in Action
Wynn Netherland, Nathan Weizenbaum, and Chris Eppstein


AttachmentSize
html5css3001.png18.32 KB
html5css3002.png28.39 KB
html5css3008.png5.25 KB
html5css3003.png28.85 KB
html5css3005.png25.33 KB
html5css3004.png76.6 KB
html5css3006.png6.06 KB
html5css3007.png10.91 KB
html5css3009.png9.32 KB
html5css3010.png4.64 KB
html5css3011.png15.57 KB
html5css3012.png26.68 KB
html5css3013.png23.4 KB
html5css3014.png37.48 KB
html5css3015.png34.57 KB
html5css3016.png7.48 KB
html5css3017.png46.22 KB
html5css3018.jpg9.84 KB
html5css3019.jpg24.42 KB
html5css3020.png28.49 KB

Comments

As you mention that writing cross browser code is not ...

As you mention that writing cross browser code is not straight forward which results in every-time using dojo or jquery based animations. But again, solely using these javascript frameworks for one odd feature or page in a web application is not justified. At least we have an alternative for it in HTML only.