Not your average Drag and Drop

Ryan Seddon

font dragr

DnD is an IE API

Shipped in IE5.5

That's why it's UGLY

To accept a drop you need to cancel two other events, lolwut?


var body = document.body;

body.addEventListener("dragover", function(e) {
    e.preventDefault();
}, false);

body.addEventListener("dragenter", function(e) {
    e.preventDefault();
}, false);

body.addEventListener("drop", function(e) {
    // Now we can get to Drop
}, false);
                    

FileReader

Allows you to read files into memory

Mozilla did it first

DnD API has files property


body.addEventListener("drop", function(e) {
    var files = e.dataTransfer.files,
        // This is used to load files into memory
        reader = new FileReader();

    // FileReader is async so we attach a listener
    reader.addEventListener("loadend", function(e) {
        // e.target.result contains the base64 string
    }, false);

    // Get file and turn it into a base64 string
    reader.readAsDataURL(files[0]);

    e.preventDefault();
}, false);
                    

Blob URLs

Reference the file directly


body.addEventListener("drop", function(e) {
    var files = e.dataTransfer.files,
        url = window.URL || window.webkitURL;

    alert(url.createObjectURL(files[0]));

    e.preventDefault();
}, false);
                    

FileReader

  • Firefox 3.6+
  • Chrome 6+
  • Opera 11+*
  • IE10+

Blob URLs

  • Firefox 4+
  • Chrome 8+
  • IE10+

Dragging

You can attach data to a drag event

Two things


<div class="drag" id="drag" draggable="true"></div>
                    

[draggable='true'] {
  -khtml-user-drag: element;
  -webkit-user-drag: element;
  -khtml-user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
  user-select: none;
}
                    

Set/get drag data


drag.addEventListener("dragstart", function(e) {
    var dt = e.dataTransfer,
    // IE doesn't like anything other than "Text"
    type = /*@cc_on!@*/0 ? "Text" : "text/plain";
    dt.setData( type, "Some data to set" );
}, false);

drop.addEventListener("drop", function(e) {
    var dt = e.dataTransfer,
    // IE doesn't like anything other than "Text"
    data = dt.getData( /*@cc_on!@*/0 ?
    "Text" : "text/plain" );
    alert(data);
}, false);
                    

Bonus feature

Drag a file out of the browser*


dragout.addEventListener("dragstart", function(e) {
  var dt = e.dataTransfer;

  data = dt.setData( "DownloadURL", "application/octet-stream:Eadui.ttf:http://example.com/Eadui.ttf" );
}, false);
                    

* Proprietary, Chrome only see my article about it

Thanks!