Apparently, this problem is more recurring than I thought, since I found at least 5 questions related to the same topic (and I will answer all questions related to this problem).
Unlike mouse hovering, the dragover and dragleave events do not treat children as a single entity, so every time the mouse passes over any of the children, dragleave fires.
Thinking about downloading files, I created a widget that allows you to:
- Drag and Drop Desktop Files Using $ _FILES
- Drag images / elements or URLs to the browser using $ _POST and cURL
- Attach a device file with a button using $ _FILES
- Use input to write / paste images / URL elements with $ _POST and cURL

Problem: since everything, both the input data and the images, are inside the children of the DIV, the dragleave was launched even if it did not leave the dashed line. Using the "pointer-events: none" attribute is not an alternative, as methods 3 and 4 should trigger "onchange" events.
Decision? An overlapping DIV that covers the entire drop container when the mouse enters, and the only one with children with "pointer-events: none".
Structure:
- div # drop-container: main div, keep everything together
- div # drop-area: dragenter listener and # drop-pupup intermediate trigger
- div # drop-pupup: at the same level as # drop-area, "dragenter", "dragleave" and "drop" listener
Then, when the mouse enters by dragging the item into # drop-area, # drop-pupup is immediately shown forward and the events are sequentially in this div, and not in the initial receiver.

Here is the JS / jQuery code. I allowed myself to leave PoC, so do not waste all the time lost.
jQuery(document).on('dragover', '#drop-area', function(event) { event.preventDefault(); event.stopPropagation(); jQuery('#drop-popup').css('display','block'); }); jQuery(document).on('dragover dragleave drop', '#drop-popup', function(event) { event.preventDefault(); event.stopPropagation(); console.log(event.type);
body { background: #ffffff; margin: 0px; font-family: sans-serif; } #drop-container { margin: 100px 10%; width: 80%; display: block; float: left; overflow: hidden; box-sizing: content-box; position: relative; border-radius: 5px; text-align: center; cursor: default; border: 2px dashed #000000; } #drop-area { display: block; float: left; padding: 10px; width: 100%; } #drop-popup { display: none; box-sizing: content-box; position: absolute; width: 100%; top: 0; left: 0; background: linear-gradient(to BOTTOM, rgba(245, 245, 245, 1) , rgba(245, 245, 245, 0)); height: 512px; padding: 20px; z-index: 20; } #drop-popup > p { pointer-events: none; }
<html> <head> <title>Drag and Drop</title> </head> <body> <div id="drop-container"> <div id="drop-area"> <p>Child paragraph content inside drop area saying "drop a file or an image in the dashed area"</p> <div>This is a child div No. 1</div> <div>This is a child div No. 2</div> </div> <div id="drop-popup"> <p>This DIV will cover all childs on main DIV dropover event and current P tag is the only one with CSS "pointer-events: none;"</p> </div> </div> <script src="https://code.jquery.com/jquery-3.4.1.min.js" type="text/javascript"></script> </body> <html>
About jQuery "on", use it with the div id enabled so that you can fire event triggers that trigger a hidden "load box"
Finally, I preferred to use a dragover instead of a dragenter because it has a small delay (milliseconds), which contributes to performance ( https://developer.mozilla.org/en-US/docs/Web/API/Document/dragover_event ),
Benjamin May 18 '19 at 5:11 a.m. 2019-05-18 05:11
source share