Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 971
Rudolf Gröhling Avatar asked Jun 30 '17 08:06

Rudolf Gröhling


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.

like image 89
George Robinson Avatar answered Oct 12 '22 23:10

George Robinson


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.

like image 43
hakobpogh Avatar answered Oct 12 '22 23:10

hakobpogh