Integracja danych wejściowych[type=file] z interfejsem Filesystem API

Załóżmy, że masz aplikację do edycji zdjęć i chcesz, aby użytkownicy mogli przeciągać setki zdjęć i kopiować je do aplikacji. Co robisz?

Uruchom demonstrację
Prezentacja wersji demonstracyjnej

W niedawnym poście Eiji Kitamura opisał nową, subtelną, ale potężną funkcję interfejsów API przeciągania i upuszczania: możliwość przeciągania folderów i pobierania ich jako obiektów interfejsu API systemu plików HTML5 FileEntryDirectoryEntry (wykonywane przez dostęp do nowej metody w DataTransferItem, .webkitGetAsEntry()).

Największą zaletą rozszerzenia .webkitGetAsEntry() jest to, że pozwala na eleganckie importowanie plików i całych folderów. Gdy masz obiekt FileEntry lub DirectoryEntry z zdarzenia drop, możesz zaimportować go do aplikacji, korzystając z interfejsu Filesystem API (copyTo()).

Przykład kopiowania wielu folderów do systemu plików:

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);
});

Bardzo ładnie. Ponownie, prostota wynika z integracji DnD z wywołaniami interfejsu Filesystem API.

Co więcej, możesz przeciągnąć i upuścić folder lub pliki na zwykły <input type="file">, a potem uzyskać do nich dostęp jako do wpisów w katalogu lub pliku w systemie plików. Obejmuje to:.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);

Aby zaprezentować różne techniki importowania plików i folderów, przygotowałem demonstracyjną galerię zdjęć.

Prezentacja wersji demonstracyjnej

Więcej informacji o interfejsie Filesystem API w HTML5 znajdziesz w artykule Znajomość interfejsów Filesystem API.