17

I'm searching for a cross browser solution for this. In advance i tell you that i don't want to know if is a file only, because i found solutions for that. I want to know if the file is an audio, image or video basically. In Chrome when you fire the dragenter event you can get that data from here:

ev.originalEvent.dataTransfer.items[0].type;

But in Firefox, Safari and IE the "items" spec hasn't been applyed yet: https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/items

Edit: As of late 2021, this feature is now widely supported.

In those browsers you can only see the "files" attribute:

ev.originalEvent.dataTransfer.files[0];

But on dragenter files[0] is empty. How can i workaround this to know the file type in these other browsers?

Example (Only works on Chrome):

$(document).on('dragenter', '.drop-zone', function(ev) {
  var e = ev.originalEvent;
  e.dataTransfer.dropEffect = 'copy';
  var file = e.dataTransfer.items[0];
  var type = file.type.slice(0, file.type.indexOf('/'));
  $(ev.target).html(type);
});

$(document).on('dragleave', '.drop-zone', function(ev) {
  $(ev.target).html('Drag your file over here to know the type, no need to drop it');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="drop-zone">Drag your file over here to know the type, no need to drop it</div>
cubuspl42
  • 7,833
  • 4
  • 41
  • 65
Jonathan Calb
  • 731
  • 1
  • 10
  • 28

3 Answers3

19

tl;dr version: you can't.

Edit: As of late 2021, now you can, as Data​Transfer​.items is is now widely supported.

Quoting this answer:

DRAG_OVER DOES NOT HAVE THE RIGHTS to see the data in the drag event.

It apply to both dragover and dragenter events.

Why? Well, it would be a serious privacy issue. Imagine that you have an MP3 file which for some reason you want to open in your browser. You can do that by dragging it and dropping on the browser tab bar, like that:

During the drag-and-drop process, you drag the file over the page on which you are currently on, and of course you don't want this page to know anything about this file. That's why you can't get information about dragged file until it has been actually dropped.


You can, however, check the file type on drop event:

"drop dragover".split(" ").forEach(function(eventName) {
  document.addEventListener(eventName, function(event) {
    event.preventDefault();
  });
});
document.addEventListener("drop", function(event) {
  console.log(event.dataTransfer.files[0].type);
});
html, body {
  height: 100%;
}
<p>Try dropping a file.</p>

For drag-and-drop browser support see caniuse.com.

cubuspl42
  • 7,833
  • 4
  • 41
  • 65
Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
  • 2
    I don't think this responds my question. Currently i can know the file type in the drag event (Chrome) with the "DataTransfer.items" property. The spec says: "The DataTransfer.items property is a list of the data transfer items in a drag operation. The list includes one item for each item in the operation and if the operation had no items, the list is empty."; But in other browsers this spec is not applied yet. My question is if there is today any workaround for this. Also, my question is NOT about the drop event. I already know how to do it with that. – Jonathan Calb Jan 20 '16 at 15:40
  • @JonathanCalb You simply CAN'T do that. As I already wrote, it would be a security issue. If it works in Chrome (which I doubt; code snippet or didn't happen), it's a bug, not a feature. – Michał Perłakowski Jan 20 '16 at 15:44
  • 2
    Working code snippet added. And I don't think its a bug, if you read the spec it does what it say it should do. – Jonathan Calb Jan 21 '16 at 17:19
  • @JonathanCalb Even if you're right, I don't think there is a cross-browser solution for now. – Michał Perłakowski Jan 21 '16 at 18:17
  • This didn't respond my question. You end up responding that you don't think there is a cross-browser solution for now. If that's your final answer I need you explain it in depth. – Jonathan Calb Jan 26 '16 at 14:53
  • @JonathanCalb How can I explain that there isn't a cross browser solution? It's a new API, so how possibly it could be supported by all browsers? I explained what can be explained: why I think it would be a privacy issue and how to achieve this with `drop` event instead. – Michał Perłakowski Jan 26 '16 at 15:13
  • Also, `DataTransfer.items` is still in status of Working Draft (which means that specification may change). – Michał Perłakowski Jan 26 '16 at 15:19
  • @MichałPerłakowski I believe that the dispute is finally resolved, as the `.items` property is now widely supported and all browsers (thankfully) include this security issue, which I'd call a useful feature with a good usability/security ratio. – cubuspl42 Dec 06 '21 at 15:04
4

Data​Transfer​.items appears to be the only possibility. It is now supported on Firefox, only Safari and IE don't support it.

Zwyx
  • 349
  • 4
  • 7
0

Didnt found answer here, but this solution help me:

Just check event?.dataTransfer?.types on event dragenter.

['Files'], ['text/plain', 'text/html'] and other types

Indy660
  • 191
  • 1
  • 5