Базовый курс JavaScript
-
1. Вступление. Подготовка к работе. console.log
-
2. Типы данных, операторы, методы и свойства
-
3. Динамическая типизация. Условия if, swith
-
4. Логические операторы. Функции
-
5. Функции declaration/expression. Область видимости
-
6. Объекты, массивы
-
7. Циклы while и for
-
8. Методы массивов
-
Практика 1.
-
10. Доступ к элементам в DOM. Доступ к элементам
-
11. Изменение документа. Практика: Галерея
-
12. Добавление событий
-
13. Всплытие и погружение. Объект события.
-
14. Объект Math. localStorage
-
15. Практика
-
16. Дата. This
-
17. Асинхронность js. Promise.
-
18. Практика
13. Всплытие и погружение. Объект события.
Всплытие и погружение
Давайте начнём с примера.
Этот обработчик для
сработает, если вы кликните по любому из вложенных тегов, будь то или
:
<div onclick="alert('Обработчик!')">
<em>Если вы кликните на <code>EM</code>, сработает обработчик на <code>DIV</code></em>
</div>
Вам не кажется это странным? Почему же сработал обработчик на
, если клик произошёл на ?
Всплытие
Принцип всплытия очень простой.
Когда на элементе происходит событие, обработчики сначала срабатывают на нём, потом на его родителе, затем выше и так далее, вверх по цепочке предков.
Например, есть 3 вложенных элемента FORM > DIV > P
с обработчиком на каждом:
<style>
body * {
margin: 10px;
border: 1px solid blue;
}
</style>
<form onclick="alert('form')">FORM
<div onclick="alert('div')">DIV
<p onclick="alert('p')">P</p>
</div>
</form>
Клик по внутреннему
вызовет обработчик onclick
:
- Сначала на самом
- Потом на внешнем
- Затем на внешнем
. - И так далее вверх по цепочке до самого
document
.
Поэтому если кликнуть на
, то мы увидим три оповещения: p
→ div
→ form
.
Этот процесс называется «всплытием», потому что события «всплывают» от внутреннего элемента вверх через родителей подобно тому, как всплывает пузырёк воздуха в воде.
Ключевое слово в этой фразе – «почти».
Например, событие focus
не всплывает. В дальнейшем мы увидим и другие примеры. Однако, стоит понимать, что это скорее исключение, чем правило, всё-таки большинство событий всплывают.
event.target
Всегда можно узнать, на каком конкретно элементе произошло событие.
Самый глубокий элемент, который вызывает событие, называется целевым элементом, и он доступен через event.target
.
Отличия от this
(=event.currentTarget
):
event.target
– это «целевой» элемент, на котором произошло событие, в процессе всплытия он неизменен.this
– это «текущий» элемент, до которого дошло всплытие, на нём сейчас выполняется обработчик.
Например, если стоит только один обработчик form.onclick
, то он «поймает» все клики внутри формы. Где бы ни был клик внутри – он всплывёт до элемента
Попробуйте сами:
Возможна и ситуация, когда event.target
и this
– один и тот же элемент, например, если клик был непосредственно на самом элементе
Объект события
Чтобы хорошо обработать событие, могут понадобиться детали того, что произошло. Не просто «клик» или «нажатие клавиши», а также – какие координаты указателя мыши, какая клавиша нажата и так далее.
Когда происходит событие, браузер создаёт объект события, записывает в него детали и передаёт его в качестве аргумента функции-обработчику.
Пример ниже демонстрирует получение координат мыши из объекта события:
<input type="button" value="Нажми меня" id="elem">
<script>
elem.onclick = function(event) {
// вывести тип события, элемент и координаты клика
alert(event.type + " на " + event.currentTarget);
alert("Координаты: " + event.clientX + ":" + event.clientY);
};
</script>
Некоторые свойства объекта event
:
event.type
- Тип события, в данном случае
"click"
. event.currentTarget
- Элемент, на котором сработал обработчик. Значение – обычно такое же, как и у
this
, но если обработчик является функцией-стрелкой или при помощиbind
привязан другой объект в качествеthis
, то мы можем получить элемент изevent.currentTarget
. event.clientX / event.clientY
- Координаты курсора в момент клика относительно окна, для событий мыши.
Есть также и ряд других свойств, в зависимости от типа событий, которые мы разберём в дальнейших главах.
При назначении обработчика в HTML, тоже можно использовать объект event
, вот так:
<input type="button" onclick="alert(event.type)" value="Тип события">
Это возможно потому, что когда браузер из атрибута создаёт функцию-обработчик, то она выглядит так: function(event) { alert(event.type) }
. То есть, её первый аргумент называется "event"
, а тело взято из атрибута.