Управление событиями в javascript
Механизм DOM - события призваны помочь разработчику перехватить и обработать различные действия от пользователей (клики мышкой по элементам, нажатия клавиш и прочее).
Почти все события состоят из двух фаз:
- - capturing (захват, или погружение)
- - bubbling (всплытие)
Разработчик может установить свой обработчик события на любую из фаз.
Когда происходит событие, информация о нем спускается от корневого элементам dom-дерева вниз, до того элементам, на котором произошло событие (например, если кликнули по ссылке, то событие спускается от корня дерева до ссылки). Этот процесс называется фазой захвата (capture).
То есть браузер посылает информацию о событии (event) от корня (html) вниз.
После этого, процесс начинается в обратном порядке. То есть информация о событии поднимается от элемента, на котором произошло событие до корневого элемента dom-дерева. Этот процесс называется фазой всплытия (bubble).
После того, как событие “всплывет” происходит действие по умолчанию.
Например для ссылок, действием по умолчанию является переход на сайт,
заданный в атрибуте href
.
Иногда говорят так:
- 1 ФАЗА - Погружение
- 2 ФАЗА - Выполнение обработчиков (выше мы описали 2 фазы)
- 3 ФАЗА - Всплытие и действие по умолчанию (после всплытия)
Данный механизм нужен для перехвата событий.
Установка обработчиков события через метод addEventListener
EventTarget.addEventListener(event, handler, inCapture)
-
Добавляем новый обработчик события к
EventTarget
. -
handler
будет выполняться при каждом событии event происходящем сEventTarget
. -
Если
inCapture
равенtrue
, то обработчик будет выполняться не на фазе всплытия (bubble), а на фазе захвата/погружения (capture)
var button = document.querySelector('button');
//При помощи addEventListener, вы можете задавать
//несколько обработчиков события
button.addEventListener('click', function() {
alert('click');
})
button.addEventListener('click', function() {
alert('second');
})
Удаление обработчиков события через метод removeEventListener
EventTarget.removeEventListener(event, handler)
Удаляем у EventTarget
обработчик handler
события event
.
function handler1() {
console.log('обработчик 1');
}
function handler2() {
console.log('обработчик 2');
}
var button = document.querySelector('button');
button.addEventListener('click', handler1);
button.addEventListener('click', handler2);
button.removeEventListener('click', handler2);
Обратите внимание, что при удалении обработчика, необходимо указать переменную с функцией-обработчиком. Иначе браузер не сможет удалить обработчик из элемента. Для этого, просто храните обработчики в именованных функциях или в переменных.
Объект с описанием события (event)
Когда браузер выполняет функцию-обработчик, он автоматически передает функции-обработчику первым параметром объект с информацией о событии.
Основные свойства этого объекта:
-
type
- имя события -
target
- элемент, для которого изначально было предназначено событие
или:event.target
– самый глубокий элемент, на котором произошло событие. -
currentTarget
- элемент, который перехватил событие в данный момент (элемент, на котором выполняется обработчик в данный момент)
или:event.currentTarget
(=this
) – элемент, на котором в данный момент сработал обработчик (до которого «доплыло» событие) -
eventPhase
- фаза события (захват, выполнение, всплытие)
Действие по умолчанию, а также stopPropagation
Механизм событий позволяет отменить действие по умолчанию при
помощи вызова метода preventDefault
из объекта с информацией о
событии.
link.addEventListener('click', function(e){
e.preventDefault();
});
event.stopPropagation()
остановить дальнейший ход события по дереву
event.stopImmediatePropagation()
остановить дальнейший ход события по дереву и игнорировать другие обработчики
этого же события на данном элементе
Делегирование
Делегирование - это действие по установке обработчиков событий на более высоких элементов модели DOM, чем представляющие интерес элементы.
Предположим, что у нас есть div
, внутри которого располагаются 100 button
.
Вешать обработчик события на каждую кнопку нерационально. Практичнее повесить один обработчик на вышестоящий div
. Поясню: при клике на кнопку, события об этом сначала погрузится от корня документа до кнопки, по которой произошел клик, пройдя через div
, а затем всплывет от кнопки, по которой произошел клик до корня документа, также пройдя через div
.
Мы можем повесить обработчик события click
для div
на любую фазу, и клики по любой кнопке будут так или иначе перехвачены всего лишь одним общим обработчиком. Это и есть делегирование.
<ul id="list">
<li my-attr="1">1</li>
<li my-attr="2">2</li>
<li my-attr="3">3</li>
</ul>
list.addEventListener('click', e => console.log(`кликнули на ${e.target.getAttribute('my-attr')}`))
Управление обработкой событий
Хорошая практика: каждому обрабатываемому эл-ту присвоить идентификатор (не путать с id
), а затем сохранить все связанные с ним данные в одном объекте.
Полезные статьи:
Всплытие и перехват
Комментарии к статье