Input[type=file] in das Filesystem API einbinden

Angenommen, Sie haben eine Foto-App und möchten, dass Nutzer Hunderte von Fotos per Drag-and-drop in Ihre App kopieren können. Was tun Sie?

Demo starten
Demo starten

In einem neueren Beitrag hat Eiji Kitamura eine subtile, aber leistungsstarke neue Funktion in den Drag-and-drop-APIs hervorgehoben: die Möglichkeit, Ordner per Drag-and-drop und als HTML5 Filesystem API-Objekte vom Typ FileEntry und DirectoryEntry abzurufen (durch Zugriff auf eine neue Methode des DataTransferItem, .webkitGetAsEntry()).

Das Tolle an der .webkitGetAsEntry()-Erweiterung ist, wie einfach der Import von Dateien und ganzen Ordnern damit ist. Sobald Sie eine FileEntry oder DirectoryEntry von einem Drop-Ereignis haben, können Sie sie mit der copyTo() der Dateisystem-API in Ihre App importieren.

Beispiel für das Kopieren mehrerer abgelegter Ordner in das Dateisystem:

var fs = null; // Cache filesystem for later.

// Not shown: setup drag and drop event listeners.
function onDrop(e) {
    e.preventDefault();
    e.stopPropagation();

    var items = e.dataTransfer.items;

    for (var i = 0, item; item = items[i]; ++i) {
    var entry = item.webkitGetAsEntry();

    // Folder? Copy the DirectoryEntry over to our local filesystem.
    if (entry.isDirectory) {
        entry.copyTo(fs.root, null, function(copiedEntry) {
        // ...
        }, onError);
    }
    }
}

window.webkitRequestFileSystem(TEMPORARY, 1024 * 1204, function(fileSystem) {
    fs = fileSystem;
}, function(e) {
    console.log('Error', e);
});

Sehr schön! Die Einfachheit ergibt sich wieder aus der Einbindung von DnD in die Filesystem API-Aufrufe.

Außerdem können wir einen Ordner und/oder Dateien per Drag-and-drop auf eine normale <input type="file"> ziehen und dann auf die Einträge als Dateisystemverzeichnis oder Dateieinträge zugreifen. Das geht über .webkitEntries:

<input type="file" multiple>
function onChange(e) {
    e.stopPropagation();
    e.preventDefault();

    var entries = e.target.webkitEntries; // Get all dropped items as FS API entries.

    [].forEach.call(entries, function(entry) {

    // Copy the entry into our local filesystem.
    entry.copyTo(fs.root, null, function(copiedEntry) {
        ...
    }, onError);

    });
}

document.querySelector('input[type="file"]').addEventListener('change', onChange);

Ich habe eine Fotogalerie-Demo zusammengestellt, um diese verschiedenen Methoden zum Importieren von Dateien/Ordnern zu veranschaulichen.

Demo starten

Weitere Informationen zur HTML5-Dateisystem-API finden Sie unter Dateisystem-APIs kennenlernen.