w3c/pointerevents

Order of pointerover/enter/move and corresponding mouse events is different on browsers

Closed this issue · 8 comments

data:text/html,<input id=input><script>input.onpointerenter = input.onmouseenter = input.onpointerleave = input.onmouseleave = input.onpointerover = input.onmouseover = input.onpointerout = input.onmouseout = input.onpointermove = input.onmousemove = ev =>console.log(ev.type)</script>

When hovering over the input, the console output is:

Chrome: pointerover->pointerenter->mouseover->mouseenter->pointermove->mousemove->pointerout->pointerleave->mouseout->mouseleave
Firefox: pointerover->pointerenter->pointermove->mouseover->mouseenter->mousemove->pointerout->pointerleave->mouseout->mouseleave
Safari: pointerover->mouseover->pointerenter->mouseenter->pointermove->mousemove->pointerout->mouseout->pointerleave->mouseleave

Somehow the timing that pointermove and mousemove appear is different.

  • The pointer/mousemove happens immediately on pointerenter on all browsers
  • Events are somehow grouped on Firefox and Chrome (pointerover+pointerenter always happen together without a compatibility event between it, for example)
  • And the grouping behaviors are different.

I'm not quite sure this grouping is specced. https://w3c.github.io/pointerevents/#mapping-for-devices-that-support-hover looks like it doesn't even give the mapping for over/enter/out/leave.

@flackr @smaug---- @mustaqahmed would be interested in your thoughts on this. i don't think there was a rationale for omitting the over/enter/out/leave from the mapping for hover-capable pointers ... was it just an oversight?

on the question of exact timing, I think the spec leaves that generally unspecified, only suggesting the order in that large note in https://w3c.github.io/pointerevents/#mapping-for-devices-that-do-not-support-hover ... maybe we could do with a matching note in https://w3c.github.io/pointerevents/#mapping-for-devices-that-support-hover as well? it would still be non-normative, but could at least give an indication - or the note that's currently there could be generalised to apply to both cases, with some tweaks

The spec deliberately leaves out a direct mapping between pointer/mouse pointers for over/enter/out/leave events because the compat mouseover/enter/out/leave events must appear consistent to a mouse-events based app (that doesn't listen to Pointer Events) even when we have simultaneous primary pointers of different types ("mouse", "touch" and "pen"). The core requirement here is that the compat event sequence must consistently represent the movement of a single legacy mouse when multiple pointer-types are active at the same time. Let's look closely at an example.

Consider a mouse-press on button A followed by a touch-down a button B, before neither the mouse nor the touch is released. If we ignore the compat mouse events for a moment, the outcome is obvious:

  • the first action would fire pointerover, pointerenter and pointerdown at A with pointerType="mouse", and
  • the second action would fire pointerover, pointerenter and pointerdown at B with pointerType="touch".

Now the compat mouse events seen by buttons A and B must include the transition of a single legacy mouse pointer from A to B before the second action, so:

  • the first action would fire mouseover, mouseenter and mousedown at A, and
  • the second action would fire mouseout and mouseleave at A, followed by mouseover, mouseenter and mousedown at B.

Section 11.1 was added to clarify this idea but the discussion in this issue suggests that a textual description is not enough to explain the complexity here! Perhaps we need to add an example with a diagram?

To attempt to clarify the spec, @kevers-google helped me create this CSS animation:
https://mustaqahmed.github.io/web/pe-legacy-pointer-animation/legacy-pointer-animation.html

I am proposing to add this to the spec as a helpful note. If the spec text doesn't "like" CSS animations, we can add an animated GIF instead.

@flackr @patrickhlauke I just updated the tap timing of the above animation as per our PEWG discussion today.

@mustaqahmed So #458 added the explanation why pointerout does not directly match to mouseout, but does it actually resolve the original post?

@saschanaz see also #459 which I think more directly addresses the original post?

Ah, missed that one. Thank you!

No worries, we managed to confuse ourselves while working on these two related aspects ;)
I assume then that #459 answers the OP to your satisfaction?