What you describe is not consistent with testing, in both Chrome and Firefox, across Linux and Windows (desktop) systems. Because of the COVID situation, I don't have easy access to other browser + OS combos (I'm not exactly an Apple fan), but here's a fiddle I made where you could test any other such combo:
https://jsfiddle.net/websiter/9d7cfbmx/embedded/result/#Result
How it tests: it measures the difference in milliseconds between drop and dragend events. It also stores each of them into an array providing min, max and avg values of currently stored cases. As you can see, the difference varies in between 0.15ms and 1.75ms with average values of ~0.5ms.
Because it's a practical prototyping tool, I used Vue to update/display the stats, but that should not interfere with the events being measured at all (you'll notice they all happen and are measured outside of Vue and the data update happens in a setTimeout(), to make sure I'm not interfering with the test at all).
Unfortunately, Firefox rounds performance.now() values to 1ms, so it doesn't give you sub-millisecond min and max values, but average values seem consistent with the ones in Chrome (actually slightly smaller in my tests).
The above suggest your premise there is a 250ms delay on the dragend event is not accurate, unless both the events are delayed by the same amount of time. If that was the case, it would be visible. A quarter of a second is noticeable by human eye.
I went ahead and added a visual tester for 250ms to the above fiddle.
Another note: Looking at your demo video, you seem to be using an Apple device but it gives no clues on browser used. If I had to guess I'd say it's Safari.
Two conditions have to be met for that animation to be disabled:
- you have to call
preventDefault() on dragover event (you already do)
drop event needs to have been fired by the time dragend is (according to this answer)
In order for the second condition to happen, you could dispatch drop in dragleave if the event's related target is <html>. I really don't see another option:
document.addEventListener("dragleave", function(event) {
if (event.relatedTarget.tagName === 'HTML') {
document.dispatchEvent(new Event('drop'));
}
})
Note: by calling drop when dragging out of <html> you're breaking any case of dragging stuff out of the browser into any other programs (which, AFAIK, is one the intended uses of D&D). Also, to make sure you're only doing the dispatch when actually dragging out of the viewport, you should add this CSS bit: body { min-height: 100vh; }.
Also, as already mentioned, I have no way of testing on a Mac now, so I don't guarantee this hack works. It should, but... it's an Apple implementation, you know? Let's just say with Apple anything is possible. Maybe because it's been bitten, who knows? :)
You can test the hack here.
If the above doesn't hide the animation, this might. Look into dragend for details. (It's an attempt to not fire drop beforehand (out of principle), but rather fire it from dragend and re-dispatch a cancelable dragend mock). IMHO, worth a shot.