Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is dragleave event firing unexpectedly?

Please see the demo at - http://jsfiddle.net/fSB32/2/

My intention is that an overlay appears when drag event is fired on the document. So, the user is allowed to drag and drop images anywhere on the document. When he does so a cool overlay appears. At the completion of drag event the overlay is supposed to hide itself.

The problem I am facing is that dragleave event is getting fired unexpectedly (see console in demo), causing the overlay to hide itself as soon as it appears. If you comment out the code to hide the overlay then naturally it shows up and never goes.

like image 594
AppleGrew Avatar asked Jan 06 '14 19:01

AppleGrew


1 Answers

I figured out the issue myself.

Cause

Drag events bubble up the chain. So, it struck me that because of that when I made my overlay visible, it triggered dragenter on that and maybe on further dragging the dragleave is being triggered by its child which bubbles up to the parent where I am listening.

However, it turns out that dragleave is triggered whenever dragenter is triggered, even if the dragenter target is a child! So, in my case the moment I made the overlay visible, dragenter was triggered on it and dragleave was triggered on document and window.

The fix

So an ideal drop target must not have any children, so that dragging within itself does not trigger dragleave. In my case the drop target overlay takes the full window space so in my case it is enough to listen for dragleave only on the overlay DOM. This fixed 90% of myc problems.

However, there was the problem when user dragged over the child div inside that. The fix for that was too easy. My requirement was that I make the child div invisible to mouse events. For that we have the magic CSS - pointer-events. Setting this property to none does the trick. The only downside is that this is not supported in IE until 11.

See demo http://jsfiddle.net/fSB32/5/

If you do need to support IE below 11, then one trick could be used to put an empty div as the child in the drop target and make sure it has the highest z-index and it covers the full drop target. This way drag events should be directed only to this DOM as all other children are visible "through" it.

like image 136
AppleGrew Avatar answered Oct 12 '22 11:10

AppleGrew