Jahrelang unvorstellbar: Dateien vom Desktop in das Browserfenster ziehen...natürlich wird das betreffende Dokument dann im Browser geladen!

Dank JavaScript und HTML5 können nun allerdings Dateien per Drag & Drop auf bestimmte Objekte innerhalb einer Website gezogen und dann z.B. hochgeladen werden.

An sich keine große Sache...leider hatte ich bei den ersten Versuchen nur vergessen, an den richtigen Stellen zu verhinden, dass der Browser doch noch, kurz nachdem JavaScript das Objekt angenommen hat, die entsprechende Datei im selben Fenster anzeigt und somit alles zu Nichte macht.

Denn erst dachte ich, es würde ausreichen, die

drop
-Methode zu nehmen und mit
e.preventDefault();
den Browser davon abzuhalten, sich der hineingezogenen Datei anzunehmen.

Bringt aber nicht viel, wenn man nicht noch zusätzlich die Methode

dragover
verwendet und in dieser
e.stopPropagation(); e.preventDefault();
verwendet.

Aber nun mal eines nach dem anderen.

Grundlegender Aufbau

Ich erstelle ein
div
-Objekt, auf das ich später vom Desktop aus Dateien ziehen kann.

<div id='dropzone' style='width:400px; height:400px; border:#000000 1px solid;'></div>

Mit Hilfe der

dragover
-Methode (und nicht wie erwartet in der
drop
-Methode) verhindere ich, dass der Browser sich die Datei "schnappt", die ich auf das
div
-Objekt ziehe:

$("#dropzone").on("dragover",  function(e, ui) {
     e.stopPropagation();
     e.preventDefault();
     });

Und mit Hilfe der

drop
-Methode nun die abgelegten Dateien verarbeiten:

$("#dropzone").on("drop", function(e, ui) {
        var files = e.originalEvent.dataTransfer.files;
        // Dateien verarbeiten...
        });

Interface-Feedback

Natürlich auch schön, wenn man auf der Seite sehen kann, wo man seine Dateien hinziehen kann.
Geben wir dem

div
-Objekt einen gestrichelten Rahmen, wenn man eine Datei drauf zieht und erweitern die
dragover
-Methode dementsprechend:

$("#dropzone").on("dragover",  function(e, ui) {
     e.stopPropagation();
     e.preventDefault();
     $(this).css("border-style", "dashed");
     });
$("#dropzone").on("dragleave",  function(e, ui) {
     $(this).css("border-style", "solid");
     });

Upload-Beispiel

Meistens will man die abgelegte Datei gleich zum Server hochladen.

Hier ein kleines Beispiel, das sich nicht sehr um das Dateiformat, Asynchronität, Anzahl oder Größe schert:

$("#dropzone").on("drop", function(e, ui) {
        $(this).css("border-style", "solid");
        var files = e.originalEvent.dataTransfer.files;
        var form  = new FormData(); // Formular
        for (var i = 0; i < files.length; i++) {
                form.append('file'+i, files[i]); // Jede Datei (falls mehrere Dateien drauf gezogen wurden) bekommt ihr eigenes Formularfeld analog <input type='file'>
                }
        form.append('weitereForumlarInfos', 'blablabla'); // Weitere Infos per POST übergeben...
        form.append('nochMehrForumlarDaten', '1234'); // Weitere Infos per POST übergeben...
        $.ajax({
                url:"http://127.0.0.1/test.php", // URL
                type:"POST",
                contentType:false,
                processData:false,
                cache:false,
                data:form,
                success: function(data){
                        console.log("Alles prima");
                        }
                });
        });

Und auf der Server-Seite:

<?php
$uploaddir = './upload/';
foreach($_FILES as $file) {
        if (move_uploaded_file($file['tmp_name'], $uploaddir .basename($file['name']))) {
                // Alles OK
        } else {
                // Da stimmt doch was nicht...
                }
        }
?>