frumbert
frumbert

Reputation: 2427

drag to browser and detect mime of file being dropped

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);
    }
}

Upvotes: 1

Views: 1278

Answers (1)

Vahid
Vahid

Reputation: 7561

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.

Upvotes: 1

Related Questions