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.