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 ziehen und 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.