event.dataTransfer.files vs. event.dataTransfer.items

Viewed 7172

I'm playing with drag-and-drop API and there are two ways of gathering files from a DragEvent.dataTransfer, there is readonly files: FileList and readonly items: DataTransferItemList.

It seems that items is superset of files, gathering File[] from items is more complicated and also items are not supported in older IE, so files are easier to work with and has better support, yet the article on MDN uses items first and only when its not supported, switch to files.

My question is, if I need to gather only File[] collection from DragEvent, can I go with dataTransfer.files property or does dataTransfer.items has some benefits, which is worth?

Self Answer:

In modern browser (chrome), the files collection is empty. The dragged file is reachable only through items, so you cannot rely solely on files.

2 Answers

The major difference between dataTransfer.items and dataTransfer.files is that dataTransfer.items also contains the subdirectories.

This is important if you want to Drag&Drop subdirectories (e.g. to upload the entire directory tree, with all the files in it)

Below is an example how that would be accomplished:

function DragAndDrop_Handler(e) {
    e.preventDefault();
    
    var items = e.dataTransfer.items;
    for (var i=0; i<items.length; i++) {        
        var item = items[i].webkitGetAsEntry();  //Might be renamed to GetAsEntry() in 2020
        if (item) {
            GetFileTree(item);
        }
    }
}


function GetFileTree(item, path) {
    path = path || "";
    if (item.isFile) {

        item.file(function(file) {
            console.log(file);
        });
        
    } else if (item.isDirectory) {

        console.log(item.fullPath);  //console.log(item.name)

        // Get folder contents  
        var dirReader = item.createReader();
        dirReader.readEntries(function(entries) {
            for (var i=0; i<entries.length; i++) {
                GetFileTree(entries[i], path + item.name + "/");
            }
        });
    }
}

Note: In the Chrome browser the dataTransfer.files is deprecated and returns an empty collection.

I also didn't find any proper explanation of the difference between that two APIs. But after my experiments on that API, I found out that the dataTransfer.items is much newer and is defined to provide not just file drops but also drag and drop functionality(i.e. when you want to drag some item from your page to another part of your page). And since I don't care about old IEs I'm only using dataTransfer.items.

Related