Tích hợp input[type=file] với API Filesystem

Giả sử bạn có một ứng dụng chỉnh sửa ảnh và bạn muốn người dùng có thể kéo vào hàng trăm bức ảnh và sao chép chúng vào ứng dụng đó. Vậy bạn sẽ làm gì?

Khởi chạy bản minh hoạ
Chạy bản minh hoạ

Trong một bài đăng gần đây, Eiji Kitamura đã làm nổi bật một tính năng mới tinh tế nhưng mạnh mẽ trong các API kéo và thả; khả năng kéo vào các thư mục truy xuất chúng dưới dạng các đối tượng HTML5 Filesystem API FileEntryDirectoryEntry (được thực hiện bằng cách truy cập một phương thức mới trên DataTransferItem, .webkitGetAsEntry()).

Điểm thú vị đáng chú ý về tiện ích .webkitGetAsEntry() là cách tiện lợi này giúp bạn nhập tệp và toàn bộ thư mục. Sau khi có FileEntry hoặc DirectoryEntry trong một sự kiện thả, bạn cần sử dụng copyTo() của API Hệ thống tệp để nhập mã này vào ứng dụng.

Ví dụ về cách sao chép nhiều thư mục được thả vào hệ thống tệp:

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

Rất tốt! Xin nhắc lại, tính đơn giản đến từ việc tích hợp DnD với các lệnh gọi API Hệ thống tệp.

Tiến thêm một bước nữa, chúng ta cũng có thể kéo và thả thư mục và/hoặc tệp vào <input type="file"> thông thường, sau đó truy cập các mục nhập dưới dạng thư mục Hệ thống tệp hoặc mục nhập tệp. Việc này được thực hiện thông qua .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);

Tôi đã cung cấp bản minh hoạ cho thư viện ảnh để minh hoạ các kỹ thuật nhập tệp/thư mục này.

Chạy bản minh hoạ

Để tìm hiểu thêm về API hệ thống tệp HTML5, hãy xem Khám phá API hệ thống tệp.