I'm working on some drag-drop stuff right now, and as a normalization step I'd like to check if the list of objects I have are actually Files. It appears that what I normally get from event.dataTransfer is a FileList / DataTransferFileList, but the function I'm writing might end up accepting File objects from a non-event source. So, I was thinking about checking if individual items within are instances of File or DataTransferItem.
However, it seems like what I can actually get out of JS is all over the place. MDN tells me that DataTransfer.files contains a FileList; Chrome Devtools shows it as a DataTransferItemList (in the console). An item within the list should be a 'File', according to MDN, but Devtools shows it as a DataTransferItem. Oddly though, DataTransferItem is undefined in the Devtools console, and certainly doesn't work for an instanceof call. File, FileList, and DataTransferItemList are all there, though.
I haven't even started poking into other browsers yet....
So, my question has two parts:
What's with these variations? Does MDN preference Gecko functionality over an interpretation of the W3C spec? Am I seeing Webkit datatypes in the Devtools console, but these datatypes don't necessarily translate to anything accessible (i.e. a JS constructor) in JS that I can use to instanceof?
How can I tell if something is a list of Files, given all these variations? Should I be relying on some duck typing solution instead of instanceof?
So I ended up with something like this:
var knownFiles = [];
// If not already a list, make it a list
if (!files.length) {
files = [files];
}
// Iterate manually to accommodate Array, FileList, DataTransferItemList
for (i = 0; i < files.length; i++) {
file = files[i];
if (Blob && file instanceof Blob) {
// Safari, Firefox, IE land here
knownFiles.push(file);
} else if (file.webkitGetAsEntry) {
// Chrome wraps Files in DataTransferItems
knownFiles.push(file.webkitGetAsEntry());
}
}
return knownFiles;
Most of this came from poking around in browsers (Chrome 41, Safari 8, Firefox 36, and IE 11), but I also had some help from here: https://code.flickr.net/2012/12/10/drag-n-drop/.
Apparently, Chrome is the only browser that bothers with the DataTransferItemList interface, and that adds an additional layer around FileLists and Files returned in the dataTransfer property of drag/drop events.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With