|
2 | 2 |
|
3 | 3 | The idea behind shadow tree is to encapsulate internal implementation details of a component.
|
4 | 4 |
|
5 |
| -Let's say, a click event happens inside a shadow DOM of `<user-card>` component. But scripts in the main document have no idea about the shadow DOM internals, especially if the component comes from a 3rd-party library or so. |
| 5 | +Let's say, a click event happens inside a shadow DOM of `<user-card>` component. But scripts in the main document have no idea about the shadow DOM internals, especially if the component comes from a 3rd-party library. |
6 | 6 |
|
7 |
| -So, to keep things simple, the browser *retargets* the event. |
| 7 | +So, to keep the details encapsulated, the browser *retargets* the event. |
8 | 8 |
|
9 | 9 | **Events that happen in shadow DOM have the host element as the target, when caught outside of the component.**
|
10 | 10 |
|
@@ -35,11 +35,11 @@ If you click on the button, the messages are:
|
35 | 35 | 1. Inner target: `BUTTON` -- internal event handler gets the correct target, the element inside shadow DOM.
|
36 | 36 | 2. Outer target: `USER-CARD` -- document event handler gets shadow host as the target.
|
37 | 37 |
|
38 |
| -Event retargeting is a great thing to have, because the outer document doesn't have no know about component internals. From its point of view, the event happened on `<user-card>`. |
| 38 | +Event retargeting is a great thing to have, because the outer document doesn't have to know about component internals. From its point of view, the event happened on `<user-card>`. |
39 | 39 |
|
40 | 40 | **Retargeting does not occur if the event occurs on a slotted element, that physically lives in the light DOM.**
|
41 | 41 |
|
42 |
| -For example, if a user clicks on `<span slot="username">` in the example below, the event target is exactly this element, for both shadow and light handlers: |
| 42 | +For example, if a user clicks on `<span slot="username">` in the example below, the event target is exactly this `span` element, for both shadow and light handlers: |
43 | 43 |
|
44 | 44 | ```html run autorun="no-epub" untrusted height=60
|
45 | 45 | <user-card id="userCard">
|
@@ -75,7 +75,7 @@ For purposes of event bubbling, flattened DOM is used.
|
75 | 75 |
|
76 | 76 | So, if we have a slotted element, and an event occurs somewhere inside it, then it bubbles up to the `<slot>` and upwards.
|
77 | 77 |
|
78 |
| -The full path to the original event target, with all the shadow root elements, can be obtained using `event.composedPath()`. As we can see from the name of the method, that path is taken after the composition. |
| 78 | +The full path to the original event target, with all the shadow elements, can be obtained using `event.composedPath()`. As we can see from the name of the method, that path is taken after the composition. |
79 | 79 |
|
80 | 80 | In the example above, the flattened DOM is:
|
81 | 81 |
|
@@ -119,7 +119,7 @@ All touch events and pointer events also have `composed: true`.
|
119 | 119 |
|
120 | 120 | There are some events that have `composed: false` though:
|
121 | 121 |
|
122 |
| -- `mouseenter`, `mouseleave` (they also do not bubble), |
| 122 | +- `mouseenter`, `mouseleave` (they do not bubble at all), |
123 | 123 | - `load`, `unload`, `abort`, `error`,
|
124 | 124 | - `select`,
|
125 | 125 | - `slotchange`.
|
@@ -189,4 +189,4 @@ These events can be caught only on elements within the same DOM.
|
189 | 189 |
|
190 | 190 | If we dispatch a `CustomEvent`, then we should explicitly set `composed: true`.
|
191 | 191 |
|
192 |
| -Please note that in case of nested components, composed events bubble through all shadow DOM boundaries. So, if an event is intended only for the immediate enclosing component, we can also dispatch it on the shadow host. Then it's out of the shadow DOM already. |
| 192 | +Please note that in case of nested components, one shadow DOM may be nested into another. In that case composed events bubble through all shadow DOM boundaries. So, if an event is intended only for the immediate enclosing component, we can also dispatch it on the shadow host and set `composed: false`. Then it's out of the component shadow DOM, but won't bubble up to higher-level DOM. |
0 commit comments