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ć i kopiować do niej setki zdjęć. OK, co wtedy zrobić?

Uruchom wersję demonstracyjną
Uruchom prezentację

W niedawnym poście Eiji Kitamura zwrócił uwagę na subtelną, ale bardzo skuteczną funkcję interfejsów API typu „przeciągnij i upuść” – możliwość przeciągania i upuszczania folderów oraz pobierania ich jako obiektów HTML5 Filesystem API FileEntry i DirectoryEntry (w tym celu skorzystaj z nowej metody w interfejsie DataTransferItem, .webkitGetAsEntry()).

Niezwykle atrakcyjną cechą rozszerzenia .webkitGetAsEntry() jest to, że umożliwia importowanie plików i całych folderów. Gdy uzyskasz zdarzenie FileEntry lub DirectoryEntry ze zdarzenia utraty danych, możesz zaimportować go do aplikacji za pomocą interfejsu copyTo() interfejsu Filesystem API.

Przykład kopiowania wielu upuszczonych 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 dobrze! Również w tym przypadku prostota wynika z integracji DnD z wywołaniami interfejsu Filesystem API.

Co więcej, możemy też przeciągnąć i upuścić folder lub pliki do normalnego folderu <input type="file">, a następnie uzyskać dostęp do wpisów jako katalogu systemu plików lub plików. Można to zrobić do .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);

Przygotowaliśmy demonstrację galerii zdjęć, aby zademonstrować te różne techniki importowania plików i folderów.

Uruchom prezentację

Więcej informacji o interfejsie HTML5 Filesystem API znajdziesz w artykule Poznawanie interfejsów Filesystem API.