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.
getClientRectsis 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
hitClientRectproperty. It would be equivalent to calling
getClientRectsat the time of the pointer hit-test, and picking the rectangle that contains the hit point (
clientY). In this case,
offsetXis roughly equivalent to
clientX - hitClientRect.left, but in an interoperable way.