Set screen coordinates during HTML5 drag event
Categories
(Core :: DOM: Copy & Paste and Drag & Drop, defect, P2)
Tracking
()
Webcompat Priority | P3 |
People
(Reporter: sebastian, Unassigned)
References
(Blocks 2 open bugs, )
Details
(7 keywords, Whiteboard: p=0 [DevRel:P2] webcompat:risk-high)
User Story
platform-scheduled:2025-06-30
Attachments
(4 files, 5 obsolete files)
Comment 1•16 years ago
|
||
Reporter | ||
Comment 2•16 years ago
|
||
Reporter | ||
Comment 3•16 years ago
|
||
Reporter | ||
Updated•16 years ago
|
Comment 4•16 years ago
|
||
Reporter | ||
Comment 5•16 years ago
|
||
Comment 6•16 years ago
|
||
Reporter | ||
Comment 7•16 years ago
|
||
Comment 8•15 years ago
|
||
Updated•14 years ago
|
![]() |
||
Updated•14 years ago
|
![]() |
||
Comment 9•13 years ago
|
||
Comment 10•13 years ago
|
||
Comment 11•13 years ago
|
||
Comment 12•13 years ago
|
||
Comment 13•13 years ago
|
||
Comment 14•13 years ago
|
||
Comment 15•13 years ago
|
||
Comment 16•13 years ago
|
||
Comment 17•13 years ago
|
||
Comment 18•13 years ago
|
||
Comment 19•13 years ago
|
||
Comment 20•13 years ago
|
||
Comment 21•13 years ago
|
||
Comment 22•13 years ago
|
||
Comment 24•13 years ago
|
||
Comment 25•13 years ago
|
||
![]() |
||
Comment 26•13 years ago
|
||
Comment 27•13 years ago
|
||
Comment 28•13 years ago
|
||
Comment 30•13 years ago
|
||
Comment 31•13 years ago
|
||
Comment 32•13 years ago
|
||
![]() |
||
Updated•12 years ago
|
Comment 33•12 years ago
|
||
Comment 34•12 years ago
|
||
Comment 35•12 years ago
|
||
Comment 36•11 years ago
|
||
Comment 37•11 years ago
|
||
Comment 38•11 years ago
|
||
Comment 39•11 years ago
|
||
Comment 40•11 years ago
|
||
Comment 41•11 years ago
|
||
Comment 42•11 years ago
|
||
Comment 43•11 years ago
|
||
Comment 44•11 years ago
|
||
Updated•11 years ago
|
Comment 45•11 years ago
|
||
Updated•11 years ago
|
Comment 46•10 years ago
|
||
Comment hidden (off-topic) |
Comment 48•10 years ago
|
||
Comment 49•10 years ago
|
||
Comment 50•10 years ago
|
||
Updated•10 years ago
|
Comment 51•10 years ago
|
||
Comment 52•10 years ago
|
||
Comment 53•10 years ago
|
||
Comment 54•10 years ago
|
||
Updated•10 years ago
|
Comment 55•10 years ago
|
||
Comment 56•9 years ago
|
||
Comment 57•9 years ago
|
||
Comment 58•9 years ago
|
||
Updated•9 years ago
|
Updated•9 years ago
|
Updated•9 years ago
|
Comment 59•9 years ago
|
||
Comment 60•8 years ago
|
||
Updated•8 years ago
|
Comment 61•8 years ago
|
||
Comment 63•7 years ago
|
||
Comment 65•7 years ago
|
||
Updated•7 years ago
|
![]() |
||
Comment 66•7 years ago
|
||
Comment hidden (advocacy) |
Comment hidden (advocacy) |
Comment hidden (advocacy) |
Updated•5 years ago
|
Comment 70•5 years ago
|
||
Tom, can you write up a testcase to check which coordinates are missing vs. other browsers?
i.e., clientX/Y, pageX/Y, screenX/Y on different dnd events: dragstart, dragenter, dragleave, dragend, drag, dragover, dragexit, drop
thanks.
Comment 71•5 years ago
|
||
Hi Mike, I have posted a while ago (3years ago) a test case to show what is missing, see my comment here : https://bugzilla.mozilla.org/show_bug.cgi?id=505521#c59
If you try to drag the red block around, you should have the blue block following the mouse position, open the console and look at the value of pageX and pageY, they are equal to the position of the red block and not changing at all while they should correspond to the mouse X and Y position.
I haven't looked at it since then for other coordinates, but pageX and pageY are not working as intended inside the drag event.
Comment 73•5 years ago
|
||
Here's a test-case which just shows the screen coordinates during any drag event of any part of the window in the testcase. As expected, coords are always 0,0 in Firefox, but vary in Chrome.
Comment 74•5 years ago
|
||
And here's a better testcase that shows the client/page/screen coordinates for the various event types in a table, so it's easier to see what differs between browsers.
It seems that drag
events get 0,0 for all three coordinate types in Firefox, and dragend
gets 0,0 for client
and page
events, but curiously it gets screen
coordinates. The rest seem to work fine.
Chrome on the other hand returns 0,0 for the last drag
and dragleave
events as I let go of my mouse button to stop dragging, but otherwise the values seem reasonable as I drag around.
Comment 75•5 years ago
|
||
Olli, did you want to take a look too, given the above testcase?
Comment 76•5 years ago
|
||
Thanks. Will try to take a look next week.
Updated•5 years ago
|
Comment 77•5 years ago
|
||
Comment 78•5 years ago
|
||
Hello.
May I ask you, if you will decide at some time to fix that, can you please notify me by e-mail when fix is released for windows users.
As for now i had to drop support for Firefox for one of my sites since i need drop functional and i can't get drop positions. I had to ask them to download Chrome which is like not respectful to them.
Also i wanted to thank for your nice work. I'm using Firefox for more than 11 years. It's like a never-ending story of success. Everything just works.
Cheers
Comment 79•5 years ago
|
||
This also affects Directus Headless CMS https://github.com/directus/app/issues/2090
Obviously not a P1 bug, but as it's so old, hope it will get tackled. I don't want to switch away from Firefox to get my work in Directus done.
Comment 80•5 years ago
|
||
I also stubmled over this bug (that's what i call it).
I can't believe that this comment
"Note though that it doesn't specify what the properties should be set to, just that they should be set and we currently set them to 0."
from 11years ago is still state of the art.
You know what i call firefox from now on? Internet Explorer.
Comment 81•4 years ago
|
||
Got damm, spent countless of hours just to waste it all cuz FF dose not do what other browsers are doing and haven't decided to fix it for 11 years. (i thought that a such old api would be pretty stable/normalized after a decade) Now i got to use the sloppy dragover event instead. that's going to be harder to workaround since I can't keep dragging while the mouse moves outside of the container. And finding the relative offset to that container just got harder - even worse is that my container can be rotated 90deg...
Take my vote and subscription so I can follow up on this issue.
But the spec doesn't specify what it should be set to
we currently set them to 0
0 is pretty darn useless. if it don't serve any purpose why have it anyway?
if it was uncertain, couldn't someone have asked what it should have been set to?
The solution is pretty easy
- Update/specify the spec.
- Get all browser to follow the spec.
The best/easiest solution would just be to do what Blink and Safari is doing.
Not sure how IE did things - don't have access to IE anymore.
The browser differences gives me head deck. Almost wish went for mousedown + mousemove + mouseup instead of using the drag api.
Comment 82•4 years ago
|
||
luckily the workaround was a bit easy i constructed a new mouseevent and dispatched a untrusted drag event on the element being dragged to get accurate position instead of getting bounding rect and figuring out things on my own.
area.ondragover = evt => {
draggingElm.dispatchEvent(new MouseEvent('drag', evt))
evt.preventDefault()
}
Comment 83•4 years ago
|
||
Just started learning React, decided to implement a very simple draggable div element. After a couple of hours I was pulling my hair out because I couldn't understand why the mouse position was always zero, and I was sure I must be missing some fundamental programming knowledge.
Turns out it's just Firefox, the same doesn't happen on Chromium. It surprises my because I assumed full compatibility with drag and drop events would basically be a requirement to meet the needs of modern websites, but I guess I was wrong!
Comment hidden (admin-reviewed) |
Comment hidden (admin-reviewed) |
Comment hidden (admin-reviewed, advocacy) |
Comment 87•3 years ago
|
||
So, until this bug is resolved, I've written a 99% drop-in patch:
if(/Firefox\/\d+[\d\.]*/.test(navigator.userAgent)
&& typeof window.DragEvent === 'function'
&& typeof window.addEventListener === 'function') (function(){
// patch for Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=505521
var cx, cy, px, py, ox, oy, sx, sy, lx, ly;
function update(e) {
cx = e.clientX; cy = e.clientY;
px = e.pageX; py = e.pageY;
ox = e.offsetX; oy = e.offsetY;
sx = e.screenX; sy = e.screenY;
lx = e.layerX; ly = e.layerY;
}
function assign(e) {
e._ffix_cx = cx; e._ffix_cy = cy;
e._ffix_px = px; e._ffix_py = py;
e._ffix_ox = ox; e._ffix_oy = oy;
e._ffix_sx = sx; e._ffix_sy = sy;
e._ffix_lx = lx; e._ffix_ly = ly;
}
window.addEventListener('mousemove', update, true);
window.addEventListener('dragover', update, true);
// bug #505521 identifies these three listeners as problematic:
// (although tests show 'dragstart' seems to work now, keep to be compatible)
window.addEventListener('dragstart', assign, true);
window.addEventListener('drag', assign, true);
window.addEventListener('dragend', assign, true);
var me = Object.getOwnPropertyDescriptors(window.MouseEvent.prototype),
ue = Object.getOwnPropertyDescriptors(window.UIEvent.prototype);
function getter(prop,repl) {
return function() {return me[prop] && me[prop].get.call(this) || Number(this[repl]) || 0};
}
function layerGetter(prop,repl) {
return function() {return this.type === 'dragover' && ue[prop] ? ue[prop].get.call(this) : (Number(this[repl]) || 0)};
}
Object.defineProperties(window.DragEvent.prototype,{
clientX: {get: getter('clientX', '_ffix_cx')},
clientY: {get: getter('clientY', '_ffix_cy')},
pageX: {get: getter('pageX', '_ffix_px')},
pageY: {get: getter('pageY', '_ffix_py')},
offsetX: {get: getter('offsetX', '_ffix_ox')},
offsetY: {get: getter('offsetY', '_ffix_oy')},
screenX: {get: getter('screenX', '_ffix_sx')},
screenY: {get: getter('screenY', '_ffix_sy')},
x: {get: getter('x', '_ffix_cx')},
y: {get: getter('y', '_ffix_cy')},
layerX: {get: layerGetter('layerX', '_ffix_lx')},
layerY: {get: layerGetter('layerY', '_ffix_ly')}
});
})();
It borrows the coordinates from the last 'mousemove' or 'dragover' event and then implants them into the affected 'dragstart', 'drag', and 'dragend' events to replace the zero coordinates. It directly patches clientX/Y (and its alias, x/y), pageX/Y, offsetX/Y, screenX/Y, and also layerX/Y which appear to have a different issue: they're assigned to random exorbitantly large and generally constant numbers (garbage data?).
The main difference is that mouse coordinates will lag one event frame behind the true coordinates. Since the 'drag' event executes before the 'dragover' event, I don't believe there is any real way of getting the true coordinates (and 'mousemove' doesn't appear to execute at all during a drag-drop operation). Depending on the use case, this may not be a problem.
Comment 88•3 years ago
|
||
I did some testing on this and it looks like other browsers don't send the drag event at all when dragging over a different window/tab than you started the drag on. Firefox doesn't seem to either but that isn't intentional -- possibly some bug related to not dispatching the event to a child process, as the drag event does fire correctly on multiple parent process windows. The spec also doesn't have this restriction.
We could just decide that the drag event only fires when dragging over the source document and then make that the expected behaviour. That would make the coordinate handling fairly clear to implement, since the coordinates would be relative to the document being dragged over which is the same as the drag event target document.
Given this, this does mean that the workaround for this bug is to just use the dragover event instead since it does include the coordinates in the event, but just fires on a different target in the same document.
One other note is that Chromium has an oddity when dragging over a subframe from the same host: the coordinate of the drag event is relative to the subframe document being dragged over rather than the parent document.
Comment 89•3 years ago
|
||
This also more intentionally limits firing the drag event so that it only fires when dragging over the same document that the drag started in. This seems to be what other browsers do and we do unintentionally because we don't handle it in multiprocess. The only noticable behaviour change would be between parent process windows but the drag event is not used there except in tests.
Updated•3 years ago
|
Updated•3 years ago
|
Comment hidden (admin-reviewed) |
Comment hidden (admin-reviewed) |
Comment hidden (admin-reviewed) |
Comment 93•3 years ago
|
||
I checked today and this issue is still occurring (firefox version 99).
I can see no way to extract pointer input while a drag operation is occurring in firefox. There is no full workaround for this issue right now that I can see.
I am looking to create a general purpose drag and drop framework that sits on top of the browser drag and drop API. It is common to want to know where abouts a user pointer is so that you can do things like:
- drawing
- detect the closest edge of a drop target
- resizing
Will this issue be actioned? It is already 13 years old, and I would love to see firefox become in sync with Chrome and Safari
Comment 94•3 years ago
|
||
Firefox is violating the drag and drop spec
"If there is no relevant pointing device, then initialize event's screenX, screenY, clientX, clientY, and button attributes to 0"
Firefox is setting all attributes to 0
even when there is a relevant pointing device
Comment 95•3 years ago
|
||
Update for others:
I have found that firefox does publish position information (clientX
, clientY
and friends) for all drag and drop events other than drag
- ✅
"dragstart"
- ✅
"dragenter"
- ✅
"dragleave"
- ✅
"dragover"
- ✅
"drop"
- ✅
"dragend"
- ❌
"drag"
In order to get drag
like information:
- add an event listener to a fairly high
EventTarget
(egwindow
) - listen for
dragover
events. (dragover
fires whenever you are over a potential drop target, which is everyElement
) - 💰 profit: effectively get a
drag
event by repurposingdragover
Comment 96•3 years ago
|
||
The patch here had some issues with how the coordinates were handled in some cases, but I don't remember what they were and don't have time right now to investigate.
The workaround is to just use the dragover event as described above to get behaviour similar to Chrome/Webkit/etc.
Updated•2 years ago
|
Comment 97•2 years ago
|
||
The severity field for this bug is relatively low, S3. However, the bug has 4 duplicates, 29 votes and 67 CCs.
:enndeakin, could you consider increasing the bug severity?
For more information, please visit auto_nag documentation.
Comment 98•2 years ago
|
||
The last needinfo from me was triggered in error by recent activity on the bug. I'm clearing the needinfo since this is a very old bug and I don't know if it's still relevant.
Comment hidden (metoo) |
Comment hidden (advocacy) |
Comment 101•1 year ago
|
||
(In reply to Alex Reardon from comment #95)
Update for others:
I have found that firefox does publish position information (
clientX
,clientY
and friends) for all drag and drop events other thandrag
- ✅
"dragstart"
- ✅
"dragenter"
- ✅
"dragleave"
- ✅
"dragover"
- ✅
"drop"
- ✅
"dragend"
- ❌
"drag"
In order to get
drag
like information:
- add an event listener to a fairly high
EventTarget
(egwindow
)- listen for
dragover
events. (dragover
fires whenever you are over a potential drop target, which is everyElement
)- 💰 profit: effectively get a
drag
event by repurposingdragover
Bug still present.
Following this comment, here is what I did to implement it.
Hop this help:
let dragoverFixAdded = false,
lastWindowDragEvent = false;
const fillEventClientPosition = (e) => {
e.clientPosition = {
x: e.clientX,
y: e.clientY,
};
if (e.clientX || e.clientY) {
// We're fine
return;
}
if (!dragoverFixAdded) {
window.addEventListener('dragover', (e) => {
lastWindowDragEvent = e;
});
}
if (lastWindowDragEvent && e.timeStamp - lastWindowDragEvent.timeStamp < 100) {
// We can use the lastWindowDragEvent, it's not too old
e.clientPosition = {
x: lastWindowDragEvent.clientX,
y: lastWindowDragEvent.clientY,
};
}
};
item.addEventListener('drag', (e) => {
fillEventClientPosition(e);
// Use e.clientPosition.x, e.clientPosition.y
});
Comment 104•1 year ago
|
||
Seems there is a similar issue with the click event on a select and select options in a modal
Comment 105•1 year ago
|
||
It's weird that I end up on this page for the 3rd time in the last few years, trying to debug why different drag/drop parts aren't working.
How come a bug like this even lives for 15 years? I would expect that even less severe bugs (although this is S2 which theoretically should be fixed within 1 release cycle) would get more attention as they get old.
Comment 106•1 year ago
|
||
Sorry, but is there an ETA for this issue?
Unfortunately the work around in comment #101 no longer works because the drag event on an element prevents the window dragover from firing.
Comment hidden (advocacy) |
Comment 108•5 months ago
|
||
One note here is that no browser implements the drag event at all like what the spec says, and the spec is vague about what the coordinates for the drag event should be set to.
Implementing this would likely require reverse engineering what Chrome does. Chrome's behaviour is nonsensical when frames are involved for example, so I don't see doing this as an ideal solution.
I'm not sure what comment 106 is referring to. The dragover event fires just fine and includes the coordinates where the mouse pointer is located.
Comment 109•4 months ago
|
||
According the Specification:
If there is no relevant pointing device, then initialize event's screenX, screenY, clientX, clientY, and button attributes to 0.
And the DragEvent interface is extended from MouseEvent.
So the position properties should seem like mousemove when relevant pointing device exists.
Updated•4 months ago
|
Updated•4 months ago
|
Updated•2 months ago
|
Comment 110•2 months ago
|
||
Updated•2 months ago
|
Description
•