27.072015

Drag&Drop mit JavaScript

Hallo freunde der Frontend Entwicklung,

heute gibt mal was ganz neues... DRAG&DROP! Ja ich weiß, das Thema ist gar nicht neu, wir haben es auch schon diverse male in unserem Technik Blog behandelt. Heute möchte ich aber mal eine andere Seite beleuchtet, nämlich wie Drag&Drop von Dateien in den Browser löst, ohne ein aufgeblasenes Framework und ohne Schischi, nur mit JavaScript.
Egg_Mountain
Leider wird die File API noch nicht von allen Browsern unterstützt, wenn ich nicht alle schreibe meine ich den Internet Explorer  (Version 8 und 9). Aber diese Dinos sollten uns nicht von der Benutzung dieser coolen API abhalten!

1. Dropzone erstellen

Wir brauchen einen bereich auf der Seite auf den wir Dateien via Drag&Drop schieben können.

Bislang öffnet der Browser einfach die Datei die wir rein ziehen, dieses verhalten wollen wir natürlich nicht. Wir erstellen in unserer HTML-Datei einen Bereich in dem die User später ihre Dateien ziehen können:

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <style type="text/css">
  .dropzone {
    box-sizing: border-box;
    width: 300px;
    height: 300px;
    background: #ccc;
    border: 2px dashed #666;
    text-align: center;
    color: #666;
    padding-top: 30%;
  }
  </style>
</head>
<body>
<div class="dropzone">
  Datei hier rein ziehen
</div>
</body>
</html>

1

Da es nur eine Demonstration ist muss es ja nicht gleich wunderschön aussehen ;)

2. Drag&Drop Events erstellen

Wir MÜSSEN auf drei Events "lauschen" damit der Browser nicht mehr seine Standard Aktion durchführt und die Datei versucht zu öffnen. Diese Events sind  dragover, dragenter, und drop. Wie der Name eigentlich schon sagt wird dragover die ganze Zeit aufgerufen wenn man mit einer Datei über den Bereich schwebt, dragenter wird einmal aufgerufen wenn die Datei auf den Bereich trifft (analog dazu gibt es noch dragleave, kann vielleicht für styling interessant werden) und drop welches aufgerufen wird wenn der User die Datei "fallen lässt".
Wir müssen auf diese Events horchen um die Standard Aktion zu verhindern und weil wir im drop Event etwas mit der Datei anstellen wollen

...
  Datei hier rein ziehen
</div>
<script type="text/javascript">
var cancelEvent = function(event) {
  if (event.preventDefault) {
    event.preventDefault();
  }
  return false;
};
var dropzone = document.querySelector('.dropzone');
dropzone.addEventListener('dragover', cancelEvent);
dropzone.addEventListener('dragenter', cancelEvent);
dropzone.addEventListener('drop', function(event) {
  event = event || window.event; // get window.event if e argument missing (in IE)
  if (event.preventDefault) {
    event.preventDefault();
  }
  var dt = event.dataTransfer;
  var files = dt.files;
  console.log(files);
});
</script>
</body>
...

Jetzt füllen wir den Dateinamen und den Typ einfach mal in unsere Dropzone um zu schauen ob alles
funktioniert hat:

dropzone.addEventListener('drop', function(event) {
  event = event || window.event; // get window.event if e argument missing (in IE)
  if (event.preventDefault) {
    event.preventDefault();
  }

  var dt = event.dataTransfer;
  var files = dt.files;
  var output = [];
  for (var i = 0; i < files.length; i++) {
    console.log(files[i]);
    output = output.concat([files[i].name, '(', files[i].type, ')', '<br>']);
  }
  dropzone.innerHTML = output.join('');
});

Jetzt könnt mit der Datei so einiges anstellen, z.B. mit der File API hochladen oder falls es ein Bild ist,
es einlesen und im Browser anzeigen. Viel Spaß mit euren neuen Wissen und ich hoffe ich konnte euren
Horizont ein wenig erweitern.

Zum weiterlesen:

http://www.html5rocks.com/de/tutorials/file/dndfiles/
- https://css-tricks.com/html5-progress-element/

Lizenz für das Dino Bild von Pavel.Riha.CBhttp://creativecommons.org/licenses/by-sa/3.0/