Navigate Drag and Drop Support on HTML5

, , Leave a comment

Let the users to do drag and drop interface elements, we’ve been able to do with JavaScript libraries for quite a while, but the W3C has adopted Microsoft’s Drag and Drop implementation as part of the HTML5 specification. It’s supported by most of the browsers like Firefox, Safari, Internet Explorer, and Chrome.

The implementation at first appears to be straightforward; we designate an element as ‘draggable,’ we then designate an element that watches for a dropped object, and we execute some code when that happens.

To do that, let’s create a simple drag-and-drop interface that lets us drag small images into a drop area that will load the larger version.

The HTML

{code}<div id=”images”>

<img src=”images/red_thumb.jpg”

data-large=”images/red.jpg” alt=”A red flower”>

<img src=”images/purple_thumb.jpg”

data-large=”images/purple.jpg” alt=”A white and purple flower”>

<img src=”images/white_thumb.jpg”

data-large=”images/white.jpg” alt=”A white flower”>

</div>

<div id=”preview”>

<p>Drop images here</p>

</div>{/code}
We’ r e using custom data attributes here to hold the source of the larger version of our photos.

Styling with CSS

I have created the “style.css” file into “css” folder. All our css styles will be here.
{code}<link rel=”stylesheet” href=”css/style.css” type=”text/css” >{/code}

Basic CSS

{code}#images img{

 

-webkit-user-drag

}

#images{

float: left;

width: 240px;

margin-right: 10px;

}

#preview{

float: left;

width: 500px;

background-color: #ddd;

height: 335px;

}

.hover{

border: 10px solid #000;

background-color: #bbb !important;

}{/code}

Javascript

Drag-and-Drop Events

We’ll need to work with several events related to dragging and dropping elements.

ondragstart: Fires when the user starts dragging the object

ondragend: Fires when the user stops dragging the object for any reason

ondragenter: Fires when a draggable element is moved into a drop listener

ondragover: Fires when the user drags an element over a drop listener

ondreagleave: Fires when the user drags an element out of drop listener

ondrop: Fires when the user drops an element into a drop listener successfully

ondrag:Fires when the user drags an element anywhere; fires constantly but can give X and Y coordinates of the mouse cursor

That’s a total of seven events just to handle dragging and dropping elements, and some of the events have default behaviors. If we don’t override them, the whole thing fails.

I have include jQuery from Google’s CDN.

I have created the ‘application.js’ file into ‘js’ folder. All our javascript code will be here.
{code}<script type=”text/javascript”

charset=”utf-8″

src=”http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js”>

</script>

 

<script type=”text/javascript”

src=”js/application.js”>

</script>{/code}
First, we need to define all of our list items as draggable.
{code}var contacts = $(‘#images img’);

contacts.attr(‘draggable’, ‘true’);{/code}
We’ re adding the draggable HTML5 attribute.

When we drag the image, we want to grab the address of the large image and store it. We’ll bind to the ondragstart event, and to keep it simple and cross-platform, we’ll use jQuery’s bind() method
{code}contacts.bind(‘dragstart’, function(event) {

var data = event.originalEvent.dataTransfer;

var src = $(this).attr(“data-large”);

data.setData(“Text”, src);

return true;

});{/code}
The specification provides a dataStorage mechanism that lets us specify the type of data and the data itself, which is passed along as part of the event. jQuery’s bind( ) method wraps the event in its own object.

In 2nd line we use the originalevent property to access the real event.

In line 4 We store the URL to the image on the event by using the setData( ) method using Text as the data type.

Now that we can drag elements, let’s see how to fire events when the user drops the elements.

Dropping Elements

We want our form field to act as our drop target, so we’ll locate it and bind the drop event.
{code}var target = $(‘#preview’);

 

target.bind(‘drop’, function(event) {

var data = event.originalEvent.dataTransfer;

var src = ( data.getData(‘Text’) );

 

var img = $(“<img></img>”).attr(“src”, src);

$(this).html(img);

if (event.preventDefault) event.preventDefault();

return(false);

});{/code}
We retrieve the image address we passed with the event using the get-Data( ) method on line 5, and we then create a new image element that we push into our content region.

We need to cancel the default ondrop event so it won’t fire when our user drops the element onto the target. To do that, we need to use both preventdefault( ) and return false. Internet Explorer needs return false, andother browsers need preventDefault().
{code}target.bind(‘dragover’, function(event) {

if (event.preventDefault) event.preventDefault();

return false;

});

 

target.bind(‘dragenter’, function(event) {

$(this).addClass(‘hover’);

if (event.preventDefault) event.preventDefault();

return false;

});

 

target.bind(‘dragleave’, function(event) {

$(this).removeClass(‘hover’);

if (event.preventDefault) event.preventDefault();

return false;

});{/code}

Changing Styles

We want to let the user know they have dragged an element over a drop target, and we can do that using the ondragenter and ondragleave methods.
{code}contacts.bind(‘dragend’, function(event) {

 

if (event.preventDefault) event.preventDefault();

return false;

});{/code}
This applies our hover class in our style sheet, which will be applied and removed when these events fire.

Full Javascript code

{code}$(document).ready(function() {

 

var contacts = $(‘#images img’);

contacts.attr(‘draggable’, ‘true’);

 

contacts.bind(‘dragstart’, function(event) {

var data = event.originalEvent.dataTransfer;

var src = $(this).attr(“data-large”);

data.setData(“Text”, src);

return true;

});

 

var target = $(‘#preview’);

 

target.bind(‘drop’, function(event) {

var data = event.originalEvent.dataTransfer;

var src = ( data.getData(‘Text’) );

 

var img = $(“<img></img>”).attr(“src”, src);

$(this).html(img);

if (event.preventDefault) event.preventDefault();

return(false);

});

 

target.bind(‘dragover’, function(event) {

if (event.preventDefault) event.preventDefault();

return false;

});

 

target.bind(‘dragenter’, function(event) {

$(this).addClass(‘hover’);

if (event.preventDefault) event.preventDefault();

return false;

});

 

target.bind(‘dragleave’, function(event) {

$(this).removeClass(‘hover’);

if (event.preventDefault) event.preventDefault();

return false;

});

 

contacts.bind(‘dragend’, function(event) {

if (event.preventDefault) event.preventDefault();

return false;

});

});{/code}

See the Demo

Don’t try dragging text onto form fields. Modern browsers already let you do this, but there’s no good way to override that behavior.

As it stands, we can get much better results with much less code by using a JavaScript library that supports dragging and dropping like jQuery UI.

Share this: