I expect mouseenter event will bubble from very top element down to very bottom, the same way onclick event does. Contrary it is bubbles from very bottom element to the very top element.
In Chrome, FF, IE10, and IE11 native mouseenter bubbling works as expected (from top to bottom)... Also mouseover bubbles from top to bottom, as expected, either in native or in React.
Tagging as good first issue. I don't know if it's a bug: you'd need to investigate what happens and whether it's still reproducible with React 16.
It does seem to still repro in 16: https://jsfiddle.net/bwmreymj/.
So the question is whether it's a bug or not. I don't know :-) If you have questions on this issue please post them here!
Hello, I'd love to make this my first contribution! I'll begin looking into this ASAP.
Sounds great!
After some digging, I believe that I've isolated the issue to the following for loop:
Since the loop is from the end of the array to the beginning, it causes the onMouseEnter events to fire in the reverse order than expected. I'm not sure if this was intentional or not. Since this is my first contribution, I'm also not sure if changing this code would have any unintended side effects. If it turns out that this is unintentional, and there wouldn't be any negative side effects, I will gladly submit a PR to fix it!
I have already tested that reversing the direction of the for loop produces the expected event order.
This seems to be the intended function according to the docs: https://reactjs.org/docs/events.html#mouse-events.
The onMouseEnter and onMouseLeave events propagate from the element being left to the one being entered instead of ordinary bubbling and do not have a capture phase.
The event travels up to closest common ancestor (not inclusive), then back down to the the entering node. I don't know enough about the code base to have an opinion on whether it should be changed though.
Indeed, the docs indicate it's the expected behavior. I don't know for sure what's the historical context behind this but I guess it was done because it maps more intuitively to how engineers tend to use these events. If you disagree with the rationale please file a new issue with your change proposal — but I'll close this because it doesn't seem to be a bug.
I don't think e3 -> e2 -> e1 is expected.
Because e3 is child of e2 and e2 is child of e1, thus you must enter e1 to enter e2, enter e2 to enter e3.
e1 -> e2 -> e3 should be the expected behavior. Mouseenter and Mouseout event don't bubble, and since browser find the element from the current pointer position, and then process the whole event cycle. So it's clearly that the mouseenter's mechanism is designed to trigger from ancestor to descendent. See the specs.
Because e1 has a mouseenter listener, so when pointer enter into e3, e1 should be triggered immediately. Imagine if your e3 is position absolute and be positioned out of e1's space, in this case, mouseenter on e1 should also be triggered.
But mouseover is a normal bubbling event, so the e3's mouseover would bubble to e2 and e1.
So the answer is: mouseenter/mouseout should never bubbles, they just trigger _different_ events in an order that from ancestor to descendent, instead of trigger _one event_ that bubbles from descendent to ancestor.