HTML5 Drag and Drop in IE10 PPB2

IEBlog

Internet Explorer Team Blog

HTML5 Drag and Drop in IE10 PPB2

  • Comments 50

Drag and drop is a user interaction model that we all use on a day to day basis, probably without giving it much thought. We drag files from one folder to another, text from one area of a document to another, and PowerPoint slides from one place in the presentation to another. HTML5 Drag and Drop, available in IE10 Platform Preview 2, brings this natural, familiar behavior to the Web. Magnetic Poetry on the IE Test Drive site is example of a site that uses HTML5 Drag and Drop to create an experience that previously would have needed a plug-in or JavaScript library.

Screen shot of the "Magnetic Poetry" Test Drive demo.
For an in-depth look at how this demo works, check out this video.

Before HTML5, drag and drop behavior on the Web only partially worked without JavaScript frameworks. Now making your site work well with drag and drop is simple.

Making an element draggable

While certain elements can be dragged by default (images, links and selected text), HTML5 lets you make any element draggable by setting its draggable attribute to “true.” For example, if you want to make a div draggable you would set its draggable attribute to “true”; then you can drag that div just like an image. Each magnet in the Magnetic Poetry demo is a span element with its draggable attribute set to true.

<span draggable="true" class="wordMagnet">HTML5</span>

Keep in mind that making an element draggable prevents the user from being able to select text within that element since any clicks begin a drag.

While you can set the value of the draggable attribute in markup or in script, elements also have a default draggable state. Images and links default to draggable=true while all other elements default to draggable=false.

Making an element a drop target

Just like certain elements are draggable by default, certain elements are drop targets by default. These include text input boxes and contenteditable elements. However, any element can become a drop target by properly handling the drag events.

Drag Events

When performing a drag operation, you need to consider the element you are dragging and the element you’re dragging over. Drag events fire on both these elements.

The element being dragged will receive the events:

  • dragstart – the user starts the drag
  • drag – the user is moving the element
  • dragend – the user ends the drag

The element being dragged over will receive the events:

  • dragenter –a drag enters the element’s area
  • dragleave – a drag leaves the element’s area
  • dragover – a drag is moving around the element’s area

The final event – the drop event - fires when the user drops the content. Only input elements and contenteditable elements receive this event by default. To make other elements a drop target and receive the drop event, you must call preventDefault() on the dragenter and dragover events. Here’s an example of making a div a drop target:

<div id="dropTarget">Drop Here</div>

<script>

function init() {

var dropTarget = document.getElementById("dropTarget");

dropTarget.addEventListener("dragenter", makeDrop, false);

dropTarget.addEventListener("dragover", makeDrop, false);

dropTarget.addEventListener("drop", doSomething, false);

}

 

function makeDrop(e) {

e.preventDefault();

}

</script>

In the Magnetic Poetry demo, when you pick up a magnet (dragstart) the script does some initial calculations of where within the element the mouse clicked. When you drop the magnet (dragend) the script calculates a new location for the magnet and moves it to where you dropped it.

You may also notice that when you drop a magnet, it rotates. The amount of rotation is based on how close to the middle you grab the magnet. If you grab close to the middle it will drop fairly flat but if you grab on the edges it will rotate more. This creates a more natural look.

Accessing Drag Data

When moving the magnets around the fridge, only the magnet, the element being moved, needed to perform any action so there was no need to exchange data between the element being dragged and the element being dragged over. Many other drag/drop scenarios, however, require data exchange between the drag content and the drop target. Consider a basic kids game where the goal is to drag blocks to the proper holes. When the hole receives a drop event, it needs to know what was dropped onto it in order to check if it was the proper shape.

To facilitate exchanging data between the element being dragged and the element being dropped on, drag events contain a dataTransfer object. Data may be written to the dataTransfer object only during the dragstart event and it may be read only during the drop event.

The code for the basic kids block game might look like this:

<div id="circle" draggable="true"></div>

<div id="triangle" draggable="true"></div>

<div id="circleHole"></div>

<div id="triangleHole"></div>

 

<script>

function init() {

// register the circle and triangle elements to call setShape on dragstart

// register circleHole and triangleHole to cancel the dragenter and dragover events and call checkShape on drop

}

 

function setShape(e) {

e.dataTransfer.setData("text", this.id);

}

 

function checkShape(e) {

var dropped = e.dataTransfer.getData("text");

// check for proper shape...

}

</script>

Drag and drop with files

One last new and really neat part of HTML5 drag and drop is the ability to drag a file from the desktop to a Web site. When you drop a file on a Web site, it can read the file contents and use the file within the site. The Magnetic Poetry demo uses this feature to create small image previews on the refrigerator. Drag an image file onto the refrigerator and you will get the preview.

Screen shot of the demo showing previews of drag-and-dropped images.

In order to accept file drops, the body of the page has registered for drop events. When it receives a drop event, it looks at the dataTransfer object to see if there is content in the files attribute (event.dataTransfer.files). If the drop contained a file (or multiple files), then the files attribute will contain a FileList. Each File in the array can be read through the FileReader interface. The Magnetic Poetry demo reads the file as a dataURL and then uses that as the src attribute for a new image that it creates. That way it can display the image that the user dropped in without ever uploading the file. Here’s a snippet of the code that gets and reads the file:

function dropHandler(event) {

var filelist = event.dataTransfer.files;

if (!filelist) return;

if (filelist.length > 0) {

var file = filelist[0];

var image = document.createElement('img');

image.src = "";

var filereader = new FileReader();

filereader.imageElt = image;

filereader.onloadend = handleReaderOnLoadEnd;

filereader.readAsDataURL(file);

}

}

 

function handleReaderOnLoadEnd(event) {

var image = this.imageElt;

image.src = this.result;

document.body.appendChild(image);

}

Accessibility considerations with drag and drop

Drag and drop can be a great interaction mode, however, there are users who can only use the keyboard and can’t perform a mouse drag and drop operation. If you create drag and drop experiences, you should always consider how a keyboard user would be able to complete that task.

The dropzone attribute was also added to the HTML5 spec recently in order to identify areas of the document where items can be dropped. In IE, adding the dropzone attribute does not automatically make an element a drop target; you still need to handle the drag events properly as described above. However, using it in your site signals the drop targets to any accessibility tool that chooses to use it to create more accessible drag and drop experiences.

Try it out

HTML5 drag and drop is available today in IE10 Platform Preview 2. Try it out for yourself; you can even share your poem with your friends.

—Sharon Newman, Program Manager, Internet Explorer

  • Loading...