Skip to content

Commit 926785c

Browse files
committed
правки iliakan
1 parent 91b1b2f commit 926785c

File tree

1 file changed

+23
-23
lines changed

1 file changed

+23
-23
lines changed

8-web-components/7-shadow-dom-events/article.md

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Теневой DOM и события
22

3-
Идея, стоящая за теневым DOM-деревом -- это инкапсуляция реализации внутренних деталей компонента.
3+
Смысл создания теневого DOM-дерева - это инкапсуляция внутренних деталей компонента.
44

5-
Допустим, клик произошёл внутри теневого DOM на компоненте `<user-card>`. Но скрипты основного документа ничего не знают о внутреннем устройстве теневой DOM-структуры, в особенности, если компонент из кода сторонней библиотеки или вроде того.
5+
Допустим, клик произошёл внутри теневого DOM на компоненте `<user-card>`. Но скрипты основного документа ничего не знают о внутреннем устройстве теневой DOM-структуры, в особенности, если компонент создан сторонней библиотекой.
66

7-
Таким образом, чтобы не усложнять, браузер *меняет у этого события целевой элемент*.
7+
Поэтому, чтобы не нарушать инкапсуляцию, браузер *меняет у этого события целевой элемент*.
88

9-
**События, которые пойманы в теневом DOM, но вне компонента, имеют в качестве целевого элемента -- элемент-хозяин.**
9+
**События, которые произошли в теневом DOM, но пойманы снаружи этого DOM, имеют элемент-хозяин в качестве целевого элемента `event.target`.**
1010

1111
Рассмотрим простой пример:
1212

@@ -37,9 +37,9 @@ document.onclick =
3737

3838
Хорошо, что браузер подменяет целевые элементы событий. Потому что внешний документ ничего не знает о внутреннем устройстве компонента. С его (внешнего документа) точки зрения, событие происходит на `<user-card>`.
3939

40-
**Подмена целевого элемента не происходит, если событие берёт начало на "слотовом" элементе, который фактически находится в обычном, "светлом" DOM.**
40+
**Подмена целевого элемента не происходит, если событие берёт начало на элементе из слота, который фактически находится в обычном, светлом DOM.**
4141

42-
Например, если пользователь кликнет на `<span slot="username">` из кода ниже -- целевой элемент события будет именно этим элементом для обоих обработчиков -- теневого и обычного ("светлого"):
42+
Например, если пользователь кликнет на `<span slot="username">` в примере ниже -- целевой элемент события будет именно этот `span` для обоих обработчиков -- теневого и обычного (светлого):
4343

4444
```html run autorun="no-epub" untrusted height=60
4545
<user-card id="userCard">
@@ -65,17 +65,17 @@ userCard.onclick = e => alert(`Внешний целевой элемент: ${e
6565
</script>
6666
```
6767

68-
Если клик произойдёт на `"John Smith"`, то для обоих обработчиков -- внутреннего и внешнего -- целевым элементом будет `<span slot="username">`. Это элемент обычного ("светлого") DOM, так что подмены не происходит.
68+
Если клик произойдёт на `"John Smith"`, то для обоих обработчиков -- внутреннего и внешнего -- целевым элементом будет `<span slot="username">`. Это элемент обычного (светлого) DOM, так что подмены не происходит.
6969

70-
С другой стороны, если клик произойдёт на элементе, происходящем из теневого DOM, например, на `<b>Имя</b>`, то как только всплытие выйдет за пределы теневой DOM-структуры, его `event.target` станет `<user-card>`.
70+
С другой стороны, если клик произойдёт на элементе, который находится в теневом DOM, например, на `<b>Имя</b>`, то как только всплытие выйдет за пределы теневой DOM-структуры, его `event.target` станет `<user-card>`.
7171

7272
## Всплытие и метод event.composedPath()
7373

74-
Для обеспечения всплытия событий используются развёрнутые DOM-структуры (Flattened DOM).
74+
Для обеспечения всплытия событий используется развёрнутый DOM.
7575

76-
Таким образом, если мы имеем "слотовый" (slotted) элемент и событие происходит где-то внутри него, то оно всплывает до `<slot>` и выше.
76+
Таким образом, если у нас есть элемент в слоте, и событие происходит где-то внутри него, то оно всплывает до `<slot>` и выше.
7777

78-
Полный путь изначального целевого элемента, со всеми корневыми элементами теневого DOM-дерева, можно получить, воспользовавшись методом `event.composedPath()`. Как видно из названия -- это метод, возвращающий путь, полученный после задания композиции.
78+
Полный путь к изначальному целевому элементу, со всеми теневыми элементами, можно получить, воспользовавшись методом `event.composedPath()`. Как видно из названия, этот метод возвращает путь после композиции.
7979

8080
В примере выше развёрнутое DOM-дерево будет таким:
8181

@@ -92,18 +92,18 @@ userCard.onclick = e => alert(`Внешний целевой элемент: ${e
9292
```
9393

9494

95-
Так что, при клике по `<span slot="username">` вызов метода `event.composedPath()` вернёт массив: [`span`, `slot`, `div`, `shadow-root`, `user-card`, `body`, `html`, `document`, `window`]. Что в точности отражает цепочку родителей от целевого элемента в развёрнутой DOM-структуре после задания композиции.
95+
Так что, при клике по `<span slot="username">` вызов метода `event.composedPath()` вернёт массив: [`span`, `slot`, `div`, `shadow-root`, `user-card`, `body`, `html`, `document`, `window`]. Что в точности отражает цепочку родителей от целевого элемента в развёрнутой DOM-структуре после композиции.
9696

9797
```warn header="Детали теневого DOM-дерева доступны только для деревьев с `{mode:'open'}`"
98-
Если теневое DOM-дерево было создано с `{mode: 'closed'}`, то после задания композиции путь будет начинаться с элемента-хозяина: `user-card` и дальше вверх по дереву.
98+
Если теневое DOM-дерево было создано с `{mode: 'closed'}`, то после композиции путь будет начинаться с элемента-хозяина: `user-card` и дальше вверх по дереву.
9999

100-
Этот метод работает по тем же принципам, что и остальные методы теневого DOM. Внутреннее устройство свёрнутых DOM-деревьев совершенно скрыто.
100+
Этот метод следует тем же принципам, что и остальные. Внутреннее устройство закрытых DOM-деревьев совершенно скрыто.
101101
```
102102
103103
104104
## Свойство: event.composed
105105
106-
Большинство событий успешно всплывают, выходя за границы теневого DOM. Но есть некоторые события, которые ведут себя иначе.
106+
Большинство событий успешно всплывают сквозь границу теневого DOM. Но не все.
107107
108108
Это поведение регулируется с помощью свойства `composed` объекта события. Если оно `true`, то событие пересекает границу. Иначе, оно может быть поймано лишь внутри теневого DOM.
109109
@@ -119,7 +119,7 @@ userCard.onclick = e => alert(`Внешний целевой элемент: ${e
119119
120120
Хотя есть и события, имеющие `composed: false`:
121121
122-
- `mouseenter`, `mouseleave` (также не всплывают),
122+
- `mouseenter`, `mouseleave` (они вообще не всплывают),
123123
- `load`, `unload`, `abort`, `error`,
124124
- `select`,
125125
- `slotchange`.
@@ -128,9 +128,9 @@ userCard.onclick = e => alert(`Внешний целевой элемент: ${e
128128
129129
## Генерация событий
130130
131-
Когда мы инициируем сгенерированное событие, чтобы оно всплывало за пределы компонента, нужно установить оба свойства: `bubbles` и `composed` -- со значением `true`.
131+
Когда мы генерируем своё событие, то, чтобы оно всплывало за пределы компонента, нужно установить оба свойства: `bubbles` и `composed` - в значение `true`.
132132
133-
Например, здесь мы создаём элемент `div#inner` в теневом DOM-дереве элемента `div#outer` и генерируем на нём два события. Только одно с флагом `composed: true` выйдет за пределы документа:
133+
Например, здесь мы создаём элемент `div#inner` в теневом DOM-дереве элемента `div#outer` и генерируем на нём два события. Только одно с флагом `composed: true` выйдет наружу, в документ:
134134
135135
```html run untrusted height=0
136136
<div id="outer"></div>
@@ -169,9 +169,9 @@ inner.dispatchEvent(new CustomEvent('test', {
169169

170170
## Итого
171171

172-
Только те события пересекают границы теневого DOM, чей флаг `composed` установлен в значение `true`.
172+
Только те события пересекают границы теневого DOM, у которых флаг `composed` установлен в значение `true`.
173173

174-
У большинства встроенных событий стоит `composed: true`, как и описано в соответствующих спецификациях:
174+
У большинства встроенных событий стоит `composed: true`, это описано в соответствующих спецификациях:
175175

176176
- UI Events <https://www.w3.org/TR/uievents>.
177177
- Touch Events <https://w3c.github.io/touch-events>.
@@ -180,13 +180,13 @@ inner.dispatchEvent(new CustomEvent('test', {
180180

181181
У некоторых встроенных событий всё же стоит `composed: false`:
182182

183-
- `mouseenter`, `mouseleave` (также не всплывают),
183+
- `mouseenter`, `mouseleave` (вообще не всплывают),
184184
- `load`, `unload`, `abort`, `error`,
185185
- `select`,
186186
- `slotchange`.
187187

188188
Эти события могут быть пойманы только на элементах, принадлежащих тому же DOM-дереву.
189189

190-
Если мы инициируем `CustomEvent`, то должны явно поставить флаг `composed: true`.
190+
Если мы генерируем своё событие `CustomEvent`, то должны явно поставить флаг `composed: true`.
191191

192-
Обратите внимание, что в случае вложенных компонентов, события с заданной композицией всплывают через границы всего теневого DOM. Поэтому, если событие предназначено только для непосредственного ближайшего компонента, то мы также должны инициировать это событие на элементе-хозяине. Иначе оно выйдет за пределы своего теневого DOM.
192+
Обратите внимание, что в случае вложенных компонентов теневые DOM могут быть вложены друг в друга. События с флагом `composed` всплывают через границы всех теневых DOM. Поэтому, если событие предназначено только для ближайшего внешнего компонента-родителя, мы можем инициировать его на элементе-хозяине. Тогда оно будет уже вне теневого DOM компонента, но не выплывает наружу в "ещё более внешний" DOM.

0 commit comments

Comments
 (0)