שילוב קלט[type=file] עם Filesystem API

נניח שיש לכם אפליקציה לעריכת תמונות ואתם רוצים שמשתמשים יוכלו לגרור מאות תמונות ולהעתיק אותן לאפליקציה. מה עושים?

הדגמת השקה
הדגמה של השקה

בפוסט אחרון, Eiji Kitamura הדגיש תכונה חדשה, עדינה אך חזקה, בממשקי ה-API של גרירה ושחרור: היכולת לגרור תיקיות ול לאחזר אותן כאובייקטים FileEntry ו-DirectoryEntry של HTML5 Filesystem API (הפעולה מתבצעת על ידי גישה לשיטה חדשה ב-DataTransferItem, .webkitGetAsEntry()).

היתרון הגדול של התוסף .webkitGetAsEntry() הוא האופן האלגנטי שבו הוא מאפשר לייבא קבצים ותיקיות שלמות. אחרי שמקבלים FileEntry או DirectoryEntry מאירוע השמטה, צריך להשתמש ב-copyTo() של Filesystem API כדי לייבא אותו לאפליקציה.

דוגמה להעתקת כמה תיקיות שהוזנו למערכת הקבצים:

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

יפה מאוד! שוב, הפשטות נובעת משילוב DnD עם הקריאות ל-Filesystem API.

אפשר גם לגרור ולשחרר תיקייה ו/או קבצים ל-<input type="file"> רגיל, ואז לגשת לרשומים כרשומים של קבצים או תיקיות ב-Filesystem. אפשר לעשות זאת באמצעות .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);

הכנתי הדגמה של גלריית תמונות כדי להמחיש את השיטות השונות לייבוא קבצים/תיקיות.

השקה של הדגמה

מידע נוסף על HTML5 Filesystem API זמין במאמר הסבר על ממשקי ה-API של Filesystem.