Implementing Drag and Drop Functions with HTML5 and JavaScript

With HTML5 and JavaScript, you can implement native drag and drop functions within the Web browser.

This is one of the emerging HTML5 tools that promises to make websites more interactive without relying on additional technologies such as Flash. In this tutorial we will create a simple page with images the user can drag and drop into designated areas.

Create an HTML5 Web Page

Create an HTML file for your drag and drop function. Use the following basic outline, with sections for JavaScript and CSS in the head area:

<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
/*styling here*/
</style>
<script type="text/javascript">
//functions here
</script>
</head>
<body>
<!--page elements-->
</body>
</html>

Add Drag Targets to the Page

Your page will contain elements that can be dragged and elements in which the dragged items can be dropped. Start with the areas your user will be able to drop draggable elements into, adding the following in your page body section:

<div class="pics">
<div id="place1" ondrop="dropIt(event);" ondragover="event.preventDefault();">
</div>
<div id="place2" ondrop="dropIt(event);" ondragover="event.preventDefault();">
</div>
<div id="place3" ondrop="dropIt(event);" ondragover="event.preventDefault();">
</div>
<div id="place4" ondrop="dropIt(event);" ondragover="event.preventDefault();">
</div>
<div id="place5" ondrop="dropIt(event);" ondragover="event.preventDefault();">
</div>
</div>

The draggable images in the page will be able to drop within these elements. Each has an ID to identify it within the JavaScript code. The “ondrop” event specifies a function that will execute when an item is dropped over one of these elements. The “ondragover” event simply instructs the browser not to do what it does by default, which is to prevent items being dropped within other elements – we are telling the browser to allow elements to be dropped by preventing this default behavior.

Add Draggable Elements to the Page

Let’s use a couple of image elements to drag within the page. Use the following markup for each one, altering the image source attributes for your own images:

<img src="pic1.jpg" width="80" height="80" draggable="true" ondragstart="dragIt(event);" id="pic1" />

Alter the width and height to suit your own images and give each one a unique ID attribute value. The draggable attribute instructs the browser to allow users to drag the image element. The “ondragstart” event attribute specifies a JavaScript function to execute when dragging commences. Add a couple of these inside two of your placeholder elements, resulting in markup like this:

<div class="pics">
<div id="place1" ondrop="dropIt(event);" ondragover="event.preventDefault();">
<img src="pic1.jpg" width="80" height="80" draggable="true" ondragstart="dragIt(event);" id="pic1" />
</div>
<div id="place2" ondrop="dropIt(event);" ondragover="event.preventDefault();">
<img src="pic2.jpg" width="80" height="80" draggable="true" ondragstart="dragIt(event);" id="pic2" />
</div>
<div id="place3" ondrop="dropIt(event);" ondragover="event.preventDefault();">
</div>
<div id="place4" ondrop="dropIt(event);" ondragover="event.preventDefault();">
</div>
<div id="place5" ondrop="dropIt(event);" ondragover="event.preventDefault();">
</div>
</div>

Alter the image elements to suit the name, location and dimensions of your own image files as well as your chosen IDs.

Style the Elements

Add the following declarations to the style section in your page head:

div[id^="place"]
{float:left; width:80px; height:80px; margin:3px; padding:3px; border:1px dotted #333333; background-color:#ffff99;}

These declarations apply to all elements whose ID attributes begin with “place” as our holder elements do. The shorthand notation uses a wildcard to specify this, rather than having to specify every ID attribute for the elements that your items can be dropped within. Alter the dimensions to suit your images and the styling for backgrounds or borders in any way you like. To make the demonstration clearer, you can add the following HTML at the bottom of the page:

<div class="nums">
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
</div>

Style the new elements by adding the following to your CSS code, so that you can see at a glance which element you are dragging and dropping into:

span
{float:left; width:80px; margin:3px; padding:3px; border:1px solid #999999; color:#333333;}
.pics, .nums
{clear:both; text-align:center;}

Implement Dragging

Add the following function inside the script section in your page head:

//function called when drag starts
function dragIt(theEvent) {
//tell the browser what to drag
theEvent.dataTransfer.setData("Text", theEvent.target.id);
}

If you look at your image elements you will see that this is the function specified within the “ondragstart” event attribute. The content of the function specifies the image element, letting the browser know that is what to drag. The function receives an event variable providing access to data about the element being dragged.

Implement Dropping

Add the following function after your dragging function:

//function called when element drops
function dropIt(theEvent) {
//get a reference to the element being dragged
var theData = theEvent.dataTransfer.getData("Text");
//get the element
var theDraggedElement = document.getElementById(theData);
//add it to the drop element
theEvent.target.appendChild(theDraggedElement);
//instruct the browser to allow the drop
theEvent.preventDefault();
}

This code first gets a reference to the dragged element, then adds it to the element it is being dropped in. Again, the code tells the browser not to implement the default behavior so that the image can be dropped successfully. This function also receives the event data indicating information about the dragged element and the element being dropped over.

Open your page in the browser and test it by clicking and dragging the images. Notice that if you drag the images over a page area that you have not explicitly instructed the browser to allow dropping in, they snap back to their original position. As long as you drop over a designated element, your images can be moved around. Notice also that if you drop one image on top of another, the next time you drag one, they both drag.

Conclusion

HTML5 functions bring a greatly enhanced level of interactivity to Web development. The future looks pretty exciting, but for the moment remember to take care of users with browsers that do not support these emerging techniques.

See this in action here: http://www.developerdrive.com/demo/html_dragndrop/demo.html

SHARE THIS POST
  • Bart De Kimpe

    Any chance of a demo page?

  • Romain

    I think you should consider keeping the JS stuffs in js part and not in the div / img tags as you did in the second part, using event listeners set on window.onload event :

    window.onload = function(){
    place1 = document.getElementById(“place1″); ondrop=”dropIt(event);”");
    place1.addEventListener(“drop”, function() {
    dropIt(something);
    });
    }

    etc.

    This way, HTML cares about data, JS cares about behaviour.

    • jeff_DD

      Great suggestion Romain!

  • Januardi S

    I think still have issue, when i drag pic1 or pic2 to the block where there a pic2 or pic1(I drop it), the picture i drag is gone????
    Can you fix it….

    • Nickey Khem

      i’ve got the same problem – im guessing we just have to create an if statement around?

  • http://openwebstuff.com/ Rafael

    But don’t work in Opera 11 / Linux.

  • http://www.facebook.com/theaugustleo Christopher Greene

    It may be just me, but I feel that the image being dragged should replace the image in the drag-to area.

  • samuel

    good, but the image dragged on an other make the first one disappear.. i managed to fix this, but have any idea how i could check where are the image (in which dropbox) ?
    thks !

  • Monty

    Awesome!

  • Ashwani

    can i use your information in my blog.with back link to your website

  • JimTEFL

    This is very good but nowhere in any of these website examples can I find out how to do what I call a controlled drag and drop. Take a chequers board with its 32 playing squares, sq#1 being at the top left. If a king were on sq#6 it can move onto sq#2, sq#3, sq#10 and sq#11. If I could identify the source sq# (not the king) and compare it with the target sq# I could allow drops on the above quoted sqs, the comparisons having given me 4(6-2), 3(6-3), -4(6-10) and -5(6-11).
    I have a beautiful board and can move pieces onto targets but not with the above move limitations.
    I welcome an effective solution here, please.