MouseEvent.offsetX/Y
is in an unfortunate state, especially for inline elements. Blink/WebKit calculate it from the target element’s offsetParent, and Gecko calculates it from the target element (as per spec).
This makes it impossible to get reliable offset-from-target measurements without calling getClientRects()
or another form of synchronous measurement.
This causes several issues:
- Synchronous measurements, depending on the point in which they’re done, can cause undesired additional layouts (layout thrashing)
- The client rect at the time of measurement might be different from the client-rect in the time of hit-testing, as the layout/scroll-position may have already changed by the time the event was handled.
-
getClientRects
is especially costly, as it has to account for inilne elements in split rows, transforms etc and is generally not cached by the user agent.
Proposing the following:
- The MouseEvents (and perhaps other pointer events) will come with a ready
hitClientRect
property. It would be equivalent to callinggetClientRects
at the time of the pointer hit-test, and picking the rectangle that contains the hit point (clientX
,clientY
). In this case,offsetX
is roughly equivalent toclientX - hitClientRect.left
, but in an interoperable way.