You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md
+24-14
Original file line number
Diff line number
Diff line change
@@ -46,9 +46,9 @@ That means that if the visitor is moving the mouse very fast then some DOM-eleme
46
46
47
47

48
48
49
-
If the mouse moves very fast from `#FROM` to `#TO` elements as painted above, then intermediate `<div>` (or some of them) may be skipped. The `mouseout` event may trigger on `#FROM` and then immediately `mouseover` on `#TO`.
49
+
If the mouse moves very fast from `#FROM` to `#TO` elements as painted above, then intermediate `<div>` elements (or some of them) may be skipped. The `mouseout` event may trigger on `#FROM` and then immediately `mouseover` on `#TO`.
50
50
51
-
That's good for performance, because if there may be many intermediate elements. We don't really want to process in and out of each one.
51
+
That's good for performance, because there may be many intermediate elements. We don't really want to process in and out of each one.
52
52
53
53
On the other hand, we should keep in mind that the mouse pointer doesn't "visit" all elements along the way. It can "jump".
54
54
@@ -67,38 +67,46 @@ Also move the pointer into the child `div`, and then move it out quickly down th
67
67
```
68
68
69
69
```smart header="If `mouseover` triggered, there must be `mouseout`"
70
-
In case of fast mouse movements, intermediate elements may be ignored, but one thing we know for sure: if the pointer "officially" entered an element with `mouseover`, then upon leaving it we always get `mouseout`.
70
+
In case of fast mouse movements, intermediate elements may be ignored, but one thing we know for sure: if the pointer "officially" entered an element (`mouseover` event generated), then upon leaving it we always get `mouseout`.
71
71
```
72
72
73
73
## Mouseout when leaving for a child
74
74
75
-
An important feature of `mouseout` -- it triggers, when the pointer moves from an element to its descendant.
75
+
An important feature of `mouseout` -- it triggers, when the pointer moves from an element to its descendant, e.g. from `#parent` to `#child` in this HTML:
76
76
77
-
Visually, the pointer is still on the element, but we get `mouseout`!
77
+
```html
78
+
<div id="parent">
79
+
<div id="child">...</div>
80
+
</div>
81
+
```
82
+
83
+
If we're on `#parent` and then move the pointer deeper into `#child`, but we get `mouseout` on `#parent`!
78
84
79
85

80
86
81
-
That looks strange, but can be easily explained.
87
+
That may seem strange, but can be easily explained.
82
88
83
89
**According to the browser logic, the mouse cursor may be only over a *single* element at any time -- the most nested one and top by z-index.**
84
90
85
91
So if it goes to another element (even a descendant), then it leaves the previous one.
86
92
87
-
Please note an important detail.
93
+
Please note another important detail of event processing.
88
94
89
-
The `mouseover` event on a descendant bubbles up. So, if the parent element has such handler, it triggers.
95
+
The `mouseover` event on a descendant bubbles up. So, if `#parent`has `mouseover` handler, it triggers:
90
96
91
97

92
98
93
99
```online
94
-
You can see that very well in the example below: `<div id="child">` is inside the `<div id="parent">`. There are handlers on the parent that listen for `mouseover/out` events and output their details.
100
+
You can see that very well in the example below: `<div id="child">` is inside the `<div id="parent">`. There are `mouseover/out` handlers on `#parent` element that output event details.
95
101
96
-
If you move the mouse from the parent to the child, you see two events: `mouseout [target: parent]` (left the parent) and `mouseover [target: child]` (came to the child, bubbled).
102
+
If you move the mouse from `#parent` to `#child`, you see two events on `#parent`:
103
+
1. `mouseout [target: parent]` (left the parent), then
104
+
2. `mouseover [target: child]` (came to the child, bubbled).
97
105
98
106
[codetabs height=360 src="mouseoverout-child"]
99
107
```
100
108
101
-
When we move from a parent element to a child, then two handlers trigger on the parent element: `mouseout` and `mouseover`:
109
+
As shown, when the pointer moves from `#parent` element to `#child`, two handlers trigger on the parent element: `mouseout` and `mouseover`:
If we don't examine `event.target` inside the handlers, then it may seem that the mouse pointer left `parent` element, and then came back over it. But it's not the case! The mouse never left, it just moved to the child element.
120
+
**If we don't examine `event.target` inside the handlers, then it may seem that the mouse pointer left `#parent` element, and then immediately came back over it.**
121
+
122
+
But that's not the case! The pointer is still over the parent, it just moved deeper into the child element.
113
123
114
-
If there's some action upon leaving the element, e.g. animation runs, then such interpretation may bring unwanted side effects.
124
+
If there are some actions upon leaving the parent element, e.g. an animation runs in `parent.onmouseout`, we usually don't want it when the pointer just goes deeper into `#parent`.
115
125
116
-
To avoid it, we can check `relatedTarget` and, if the mouse is still inside the element, then ignore such event.
126
+
To avoid it, we can check `relatedTarget`in the handler and, if the mouse is still inside the element, then ignore such event.
117
127
118
128
Alternatively we can use other events: `mouseenter` и `mouseleave`, that we'll be covering now, as they don't have such problems.
0 commit comments