Skip to content

Commit 05e7b7a

Browse files
committed
minor
1 parent 16d11f8 commit 05e7b7a

File tree

4 files changed

+31
-27
lines changed

4 files changed

+31
-27
lines changed

2-ui/2-events/02-bubbling-and-capturing/article.md

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,9 @@
108108
109109
Например:
110110
111-
1. Мы делаем вложенное меню. Каждое подменю обрабатывает клики на своих элементах и делает для них `stopPropagation`, чтобы не открывать внешнее меню.
111+
1. Мы делаем вложенное меню. Каждое подменю обрабатывает клики на своих элементах и делает для них `stopPropagation`, чтобы не срабатывало внешнее меню.
112112
2. Позже мы решили отслеживать все клики в окне для какой-то своей функциональности, к примеру, для статистики – где вообще у нас кликают люди. Некоторые системы аналитики так делают. Обычно используют `document.addEventListener('click'…)`, чтобы отлавливать все клики.
113-
3. Наша аналитика не будет работать над областью, где клики прекращаются `stopPropagation`. Получилась «мёртвая зона».
113+
3. Наша аналитика не будет работать над областью, где клики прекращаются `stopPropagation`. Увы, получилась "мёртвая зона".
114114
115115
Зачастую нет никакой необходимости прекращать всплытие. Задача, которая, казалось бы, требует этого, может быть решена иначе. Например, с помощью создания своего уникального события, о том, как это делать, мы поговорим позже. Также мы можем записывать какую-то служебную информацию в объект `event` в одном обработчике, а читать в другом, таким образом мы можем сообщить обработчикам на родительских элементах информацию о том, что событие уже было как-то обработано.
116116
```
@@ -134,7 +134,7 @@
134134

135135
**Ранее мы говорили только о всплытии, потому что другие стадии, как правило, не используются и проходят незаметно для нас.**
136136

137-
Обработчики, добавленные через `on<event>`-свойство или через HTML-атрибуты, или через `addEventListener(event, handler)`, ничего не знают о фазе погружения, а работают только на 2-ой и 3-ей фазах.
137+
Обработчики, добавленные через `on<event>`-свойство или через HTML-атрибуты, или через `addEventListener(event, handler)` с двумя аргументами, ничего не знают о фазе погружения, а работают только на 2-ой и 3-ей фазах.
138138

139139
Чтобы поймать событие на стадии погружения, нужно использовать третий аргумент `capture` вот так:
140140

@@ -190,7 +190,7 @@ elem.addEventListener(..., true)
190190
```
191191
192192
````smart header="На каждой фазе разные обработчики на одном элементе срабатывают в порядке назначения"
193-
Если у нас несколько обработчиков одного события, назначенных `addEventListener` на один элемент, в рамках одной фазы их порядок срабатывания - тот же, в котором они установлены:
193+
Если у нас несколько обработчиков одного события, назначенных `addEventListener` на один элемент, в рамках одной фазы, то их порядок срабатывания - тот же, в котором они установлены:
194194
195195
```js
196196
elem.addEventListener("click", e => alert(1)); // всегда сработает перед следующим
@@ -200,11 +200,9 @@ elem.addEventListener("click", e => alert(2));
200200
201201
## Итого
202202
203-
Алгоритм:
203+
При наступлении события - самый глубоко вложенный элемент, на котором оно произошло, помечается как "целевой" (`event.target`).
204204
205-
При наступлении события -- элемент, на котором оно произошло, помечается как "целевой" (`event.target`).
206-
207-
- Событие сначала двигается вниз от корня документа к `event.target`, по пути вызывая обработчики, поставленные через `addEventListener(...., true), где `true` -- это сокращение для `{capture: true}`.
205+
- Затем событие сначала двигается вниз от корня документа к `event.target`, по пути вызывая обработчики, поставленные через `addEventListener(...., true), где `true` -- это сокращение для `{capture: true}`.
208206
- Далее обработчики вызываются на целевом элементе.
209207
- Далее событие двигается от `event.target` вверх к корню документа, по пути вызывая обработчики, поставленные через `on<event>` и `addEventListener` без третьего аргумента или с третьим аргументом равным `false`.
210208
@@ -222,4 +220,4 @@ elem.addEventListener("click", e => alert(2));
222220
223221
Тоже самое справедливо для обработчиков событий. Код, который "навесил" обработчик на конкретный элемент, знает максимум деталей об элементе и его предназначении. Например, обработчик на определённом `<td>` скорее всего подходит только для этого конкретного `<td>`, он знает все о нём, поэтому он должен отработать первым. Далее имеет смысл передать обработку события родителю -- он тоже понимает, что происходит, но уже менее детально, далее – выше, и так далее, до самого объекта `document`, обработчик на котором реализовывает самую общую функциональность уровня документа.
224222
225-
Всплытие и погружение являются основой для "делегирования событий" -- очень мощного приёма обработки событий. Его мы изучим в следующей главе.
223+
Всплытие и погружение являются основой для "делегирования событий" -- очень мощного приёма обработки событий. Его мы изучим в следующей главе.

2-ui/2-events/02-bubbling-and-capturing/event-order-bubbling.svg

Lines changed: 2 additions & 2 deletions
Loading

2-ui/2-events/03-event-delegation/article.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
</table>
3131
```
3232

33-
В этой таблице всего 9 ячеек, но могло быть и 99, и даже 9999, не важно.
33+
В этой таблице всего 9 ячеек, но могло бы быть и 99, и даже 9999, не важно.
3434

35-
**Наша задача -- реализовать подсветку ячейки `<td>` при клике.**
35+
**Наша задача - реализовать подсветку ячейки `<td>` при клике.**
3636

3737
Вместо того, чтобы назначать обработчик `onclick` для каждой ячейки `<td>` (их может быть очень много) -- мы повесим "единый" обработчик на элемент `<table>`.
3838

@@ -105,13 +105,13 @@ table.onclick = function(event) {
105105
3. Если таблицы вложенные, `event.target` может содержать элемент `<td>`, находящийся вне текущей таблицы. В таких случаях мы должны проверить действительно ли это `<td>` *нашей таблицы*.
106106
4. И если это так, то подсвечиваем его.
107107

108-
## Применение делегирования: действия в разметке
108+
В итоге мы получили короткий код подсветки, быстрый и эффективный, которому совершенно не важно, сколько всего в таблице `<td>`.
109109

110-
Делегирование событий может быть использовано для оптимизации обработчиков. Мы используем один обработчик для схожих действий на многих элементах. Как мы делали это с подсветкой `<td>`.
110+
## Применение делегирования: действия в разметке
111111

112-
Но мы также можем применять делегирование, используя единый обработчик, во многих других ситуациях.
112+
Есть и другие применения делегирования.
113113

114-
Например, нам нужно сделать меню с разными кнопками: "Сохранить", "Загрузить", "Поиск" и т.д. И есть объект с соответствующими методами `save`, `load`, `search`....
114+
Например, нам нужно сделать меню с разными кнопками: "Сохранить (save)", "Загрузить (load)", "Поиск (search)" и т.д. И есть объект с соответствующими методами `save`, `load`, `search`... Как их состыковать?
115115

116116
Первое, что может прийти в голову – это найти каждую кнопку и назначить ей свой обработчик среди методов объекта. Но существует более элегантное решение. Мы можем добавить один обработчик для всего меню и атрибуты `data-action` для каждой кнопки в соответствии с методами, которые они вызывают:
117117

@@ -161,7 +161,7 @@ table.onclick = function(event) {
161161
</script>
162162
```
163163

164-
Обратите внимание, что метод `this.onClick` в строке отмеченной звёздочкой `(*)`, привязывается к контексту текущего объекта `this`. Это важно, т.к. иначе `this` внутри него будет ссылаться на DOM-элемент (`elem`), а не на объект меню, и `this[action]` будет не тем, что нам нужно.
164+
Обратите внимание, что метод `this.onClick` в строке, отмеченной звёздочкой `(*)`, привязывается к контексту текущего объекта `this`. Это важно, т.к. иначе `this` внутри него будет ссылаться на DOM-элемент (`elem`), а не на объект `Menu`, и `this[action]` будет не тем, что нам нужно.
165165

166166
Так что же даёт нам здесь делегирование?
167167

@@ -177,16 +177,16 @@ table.onclick = function(event) {
177177
Делегирование событий можно использовать для добавления элементам "поведения" (behavior), *декларативно* задавая хитрые обработчики установкой специальных HTML-атрибутов и классов.
178178

179179
Приём проектирования "поведение" состоит из двух частей:
180-
1. Элементу ставится атрибут, описывающий его поведение.
181-
2. При помощи делегирования ставится обработчик на документ, который ловит все клики (или другие события) и, если элемент имеет нужный атрибут -- производит нужное действие.
180+
1. Элементу ставится пользовательский атрибут, описывающий его поведение.
181+
2. При помощи делегирования ставится обработчик на документ, который ловит все клики (или другие события) и, если элемент имеет нужный атрибут -- производит соответствующее действие.
182182

183-
### Пример "Счётчик"
183+
### Поведение: "Счётчик"
184184

185185
Например, здесь HTML-атрибут `data-counter` добавляет кнопкам поведение: "увеличить значение при клике":
186186

187187
```html run autorun height=60
188-
Counter: <input type="button" value="1" data-counter>
189-
One more counter: <input type="button" value="2" data-counter>
188+
Счётчик: <input type="button" value="1" data-counter>
189+
Ещё счётчик: <input type="button" value="2" data-counter>
190190

191191
<script>
192192
document.addEventListener('click', function(event) {
@@ -204,14 +204,14 @@ One more counter: <input type="button" value="2" data-counter>
204204
Элементов с атрибутом `data-counter` может быть сколько угодно. Новые могут добавляться в HTML-код в любой момент. При помощи делегирования мы, фактически, добавили новый "псевдостандартный" атрибут в HTML, который добавляет элементу новую возможность ("поведение").
205205

206206
```warn header="Всегда используйте метод `addEventListener` для обработчиков на уровне документа"
207-
Когда мы устанавливаем обработчик событий на объект `document`, мы всегда должны использоваать метод `addEventListener`, а не `document.onclick`, т.к. в случае последнего могут возникать конфликты: новые обработчики будут перезаписывать уже существующие.
207+
Когда мы устанавливаем обработчик событий на объект `document`, мы всегда должны использоваать метод `addEventListener`, а не `document.on<событие>`, т.к. в случае последнего могут возникать конфликты: новые обработчики будут перезаписывать уже существующие.
208208

209209
Для реального проекта совершенно нормально иметь много обработчиков на элементе `document`, установленных из разных частей кода.
210210
```
211211
212-
### Пример "Переключатель" (Toggler)
212+
### Поведение: "Переключатель" (Toggler)
213213
214-
Ещё один пример. Сделаем так, что при клике на элемент с атрибутом `data-toggle-id` будет скрываться/показываться элемент с заданным `id`:
214+
Ещё один пример поведения. Сделаем так, что при клике на элемент с атрибутом `data-toggle-id` будет скрываться/показываться элемент с заданным `id`:
215215
216216
```html autorun run height=60
217217
<button *!*data-toggle-id="subscribe-mail"*/!*>
@@ -236,7 +236,7 @@ One more counter: <input type="button" value="2" data-counter>
236236
</script>
237237
```
238238

239-
Ещё раз заметим, что мы сделали. Теперь для того, чтобы добавить скрытие-раскрытие любому элементу, даже не надо знать JavaScript, можно просто написать атрибут `data-toggle-id`.
239+
Ещё раз подчеркнём, что мы сделали. Теперь для того, чтобы добавить скрытие-раскрытие любому элементу, даже не надо знать JavaScript, можно просто написать атрибут `data-toggle-id`.
240240

241241
Это бывает очень удобно -- не нужно писать JavaScript-код для каждого элемента, который должен так себя вести. Просто используем поведение. Обработчики на уровне документа сделают это возможным для элемента в любом месте страницы.
242242

images.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,3 +376,9 @@ proto-animal-rabbit-walk-3.svg:
376376

377377
class-inheritance-rabbit-animal-2.svg:
378378
'name: "White Rabbit"': 'name: "Белый кролик"'
379+
380+
event-order-bubbling.svg:
381+
_defaults:
382+
position: "center"
383+
'Most deeply': 'Самый глубоко'
384+
'nested element': 'вложенный элемент'

0 commit comments

Comments
 (0)