HTML5 and file Drag & Drop

Thursday 13 October 2011

There is a lot of new goodness in HTML5 and one of these features is being able to drag a file from the Windows explorer into the browser and handling the drop event using JavaScript. If you are a GMail user you are probably familiar with this as GMail allows users to attach files to emails using this Drag&Drop style.

Of course as always not every browser supports the new feature. According to 88.92% of browser support Drag&Drop, including Internet Explorer 6 and above, but it turns out this is a little optimistic as IE 9 does support Drag & Drop but not with files. This works just fine with the current versions of Chrome or FireFox though.


The HTML page I am using is real simple and looks like this.

   1: <!DOCTYPE html>
   2: <html>
   3: <head>
   4:     <title>HTML 5 Drag & Drop demo</title>
   5:     <link href="/Content/Site.css" rel="stylesheet" type="text/css" />
   6:     <script src="/Scripts/modernizr-2.0.6-development-only.js" type="text/javascript"></script>
   2: </head>
   3: <body>
   4:     <div id='dropTarget' style='height: 100px; width: 100%; background-color: Lime; text-align: center'>
   5:         Drop files here
   6:     </div>
   7:     <ul id='images'>
   8:     </ul>
   9:     <script src="../Scripts/jquery-1.6.4.js" type="text/javascript">
   1: </script>
   2:     <script>
   7: </body>
   8: </html>

A few things to note. I am using a <div> with an ID of dropTarget to drop the files from the explorer and there is an <ul> with ID images where the result of the drop is going to be shown.

Also I am using jQuery but the jQueryUI droppable function doesn’t support dragging and dropping files from the explorer at this time.


To work with file drops we need to handle 2 events, the dragover and the drop, by adding event handlers using the native addEventListener() function.

   1: $(function () {
   2:     if (Modernizr.draganddrop) {
   3:         var dropTarget = $('#dropTarget')[0];
   5:         dropTarget.addEventListener('dragover', function (e) {
   6:             e.preventDefault();
   7:         });
   9:         dropTarget.addEventListener('drop', function (e) {
  10:             e.preventDefault();
  12:             if (e.dataTransfer.files === undefined) {
  13:                 // IE doesn't support file drops yet.
  14:                 $('#dropTarget').text('Drag & Drop of files is not supported');
  15:                 return;
  16:             }
  18:             $.each(e.dataTransfer.files, function () {
  19:                 var file = this;
  20:                 $('<li>').text('#images');
  21:             });
  22:         });
  23:     }
  24:     else {
  25:         $('#dropTarget').text('Drag & Drop is not supported');
  26:     }
  27: });

The dragover event is real simple, all we need to do is prevent the browser from doing it’s default behavior.


The drop event is more interesting. First of all we need to check the passed argument to see if the is a files array on the dataTransfer object. In the case of Internet Explorer 9 this is not the case. Next we can use the $.each() function as a convenient way of handling the file drops. In this case all I am doing is showing the file name in the list.



Sweet, now it would be nice if IE also supported this API.