1

I'm trying to detect the file type of files or urls being dragged to the browser. I'd like to detect the type of file that the user has selected during the dragenter and/or dragover events.

It looks like e.dataTransfer.files returns a FileList object with length=0 during the drag enter and drag over events and it's not until a drop that the Files gets populated.

Is there any other way to determine what type the file being dragged actually might be before I allow it to be dropped (or set where it can be dropped)?

here's my initial drag and drop code:

if (window.File && window.FileList && window.FileReader) {
    if ((new XMLHttpRequest()).upload) {

        var dragHandler = {}, thisObj = undefined;
        dragHandler.IsOver = false;
        dragHandler.DragEnter = function (e) {
            e.preventDefault();
            if (e.dataTransfer.effectAllowed == "move") return;
            dragHandler.IsOver = true;
            setTimeout(function(){dragHandler.IsOver=false},0);
            document.body.className = "drag-over";
            console.log(e.dataTransfer.files); // an empty FileList :(
        };
        dragHandler.DragOver = function (e) {
            e.preventDefault();
        };
        dragHandler.DragLeave = function (e) {
            if (e.dataTransfer.effectAllowed == "move") return;
            if (!dragHandler.IsOver) {
                document.body.className = "";
            }
            dragHandler.IsOver = false;
        };
        dragHandler.Drop = function (e) {
            e.preventDefault();
            if (e.dataTransfer.effectAllowed == "move") return; // came from Sortable
            dragHandler.IsOver = false;
            $body.removeClass("drag-over");
            if (e.dataTransfer.files.length) {
                for (var i=0;i<e.dataTransfer.files.length;i++) {
                    console.log("File drop " + i, e.dataTransfer.files[i]);
                }
            } else { // dropped an url or a text selection or something else
                console.log("text/plain", e.dataTransfer.getData("text/plain"));
                console.log("text/html", e.dataTransfer.getData("text/html"));
                console.log("url", e.dataTransfer.getData("url"));
                console.log("text/uri-list", e.dataTransfer.getData("text/uri-list"));
            }
        }
        dragHandler.DragStart = function (e) {
            e.dataTransfer.effectAllowed = "move"; // don't let internal links self-drop
        }
        body.addEventListener("dragenter", dragHandler.DragEnter, false);
        body.addEventListener("dragover", dragHandler.DragOver, false);
        body.addEventListener("dragleave", dragHandler.DragLeave, false);
        body.addEventListener("drop", dragHandler.Drop, false);
        body.addEventListener("dragstart", dragHandler.DragStart, false);
    }
}
frumbert
  • 2,323
  • 5
  • 30
  • 61
  • https://stackoverflow.com/questions/11065803/determine-what-is-being-dragged-from-dragenter-dragover-events . Read both 1st and 2nd answers – Ayush Bansal Jul 10 '17 at 09:25
  • I am giving this a try myself and will keep u posted . – Ayush Bansal Jul 10 '17 at 09:26
  • [whatwg](https://html.spec.whatwg.org/multipage/dnd.html#dom-dragevent-datatransfer) says: *If the drag initiated outside of the application, the user agent must add items to the drag data store item list as appropriate for the data being dragged, honoring platform conventions where appropriate [...] and, in any case, all the drag data item type strings must be converted to ASCII lowercase.* - but [MDN](https://developer.mozilla.org/en-US/docs/Web/Events/dragenter) says the property is in protected mode. That seems wrong to me - it would be useful to be read only. – frumbert Jul 10 '17 at 22:21

1 Answers1

1

As it's said in this answer, only the drop event has a e.dataTransfer.files with actual files. If you want to check the dragged items type, you can use e.dataTransfer.items which contains DataTransferItems which has a type property.

Vahid
  • 6,639
  • 5
  • 37
  • 61