I'd like to be able to highlight the drop area as soon as the cursor carrying a file enters the browser window, exactly the way Gmail does it. But I can't make it work, and I feel like I'm just missing something really obvious.
I keep trying to do something like this:
this.body = $('body').get(0) this.body.addEventListener("dragenter", this.dragenter, true) this.body.addEventListener("dragleave", this.dragleave, true)`
But that fires the events whenever the cursor moves over and out of elements other than BODY, which makes sense, but absolutely doesn't work. I could place an element on top of everything, covering the entire window and detect on that, but that'd be a horrible way to go about it.
What am I missing?
Now HTML 5 came up with a Drag and Drop (DnD) API that brings native DnD support to the browser making it much easier to code up. HTML 5 DnD is supported by all the major browsers like Chrome, Firefox 3.5 and Safari 4 etc.
I solved it with a timeout (not squeaky-clean, but works):
var dropTarget = $('.dropTarget'), html = $('html'), showDrag = false, timeout = -1; html.bind('dragenter', function () { dropTarget.addClass('dragging'); showDrag = true; }); html.bind('dragover', function(){ showDrag = true; }); html.bind('dragleave', function (e) { showDrag = false; clearTimeout( timeout ); timeout = setTimeout( function(){ if( !showDrag ){ dropTarget.removeClass('dragging'); } }, 200 ); });
My example uses jQuery, but it's not necessary. Here's a summary of what's going on:
showDrag
) to true
on dragenter
and dragover
of the html (or body) element.dragleave
set the flag to false
. Then set a brief timeout to check if the flag is still false.This way, each dragleave
event gives the DOM enough time for a new dragover
event to reset the flag. The real, final dragleave
that we care about will see that the flag is still false.
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