DnD and Friends

by Ryan Seddon

@ryanseddon

Who am I?





A bit of history

What makes an element draggable?

<div draggable="true">
    Drag me
</div>
[draggable="true"] {
  -khtml-user-drag: element;
  -webkit-user-drag: element;
  -khtml-user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
  user-drag: element;
  user-select: none;
}

What makes an element droppable?

<div dropzone="copy f:image/*" ondrop="handleDrop(event, this)">
    Drop here!
</div>

* I could be wrong, Chrome maybe?

dataTransfer

dataTransfer

Dropping

var dropzone = document.querySelector(".dropzone");

document.querySelector(".dragr").ondragstart = function(e) {
    var dt = e.dataTransfer;
    
    dt.setData("text/plain", "I got dropped");
}
dropzone.ondrop = function(e) {
    var dt = e.dataTransfer,
        elem = this;
    
    elem.textContent = dt.getData("text/plain");
    e.preventDefault();
}
dropzone.ondragenter = function(e){e.preventDefault();}
dropzone.ondragover = function(e){e.preventDefault();}
Drop the button here
Drag me!

Rad use cases

dragout.ondragstart = function(e) {
    var dt = e.dataTransfer,
        data = this.getAttribute("data-downloadurl");
    
    dt.setData("DownloadURL", data);
}
<a href="assets/html5-cheat-sheet.pdf" 
    class="button dragout" 
    data-downloadurl="application/pdf:
                    HTML5CheatSheet.pdf:
                    http://www.thecssninja.com/demo/gmail_dragout/html5-cheat-sheet.pdf"
>Drag me to your desktop</a>

Rad use cases

Friends

Friends: FileList interface

var fileaccess = document.querySelector(".fileaccess");

fileaccess.ondrop = function(e) {
    var dt = e.dataTransfer, files = dt.files, elem = this;
    
    elem.innerHTML = files[0].name + " " + files[0].size + " " + files[0].type;
    e.preventDefault();
}
fileaccess.ondragenter = function(e){e.preventDefault();}
fileaccess.ondragover = function(e){e.preventDefault();}
Drop a file here

Friends: FileList interface

var fileinput = document.querySelector(".fileinput");

fileinput.onchange = function(e) {
    var files = fileinput.files, elem = this;
    
    elem.parentNode.innerHTML = "Name: " + files[0].name + " <br />Size: " + files[0].size + " <br />Type: " + files[0].type;
    e.preventDefault();
}

Friends: File API

var dt = e.dataTransfer, files = dt.files, elem = this,
    img = document.createElement("img"),
    reader = new FileReader();

reader.onloadend = function(file) {
    img.src = file.target.result;
    elem.appendChild(img);
}
reader.readAsDataURL(files[0]);
Drop an image here

Friends: File API

Friends: create/revokeObjectURL

var dt = e.dataTransfer, files = dt.files, elem = this,
    url = url = window.URL || window.webkitURL;

elem.innerHTML = url.createObjectURL(files[0]);
Drop an file here to see blob URL

Other use cases

Fin and thanks!