Открыть меню    

Управление событиями в 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), а затем сохранить все связанные с ним данные в одном объекте.

Полезные статьи:
Всплытие и перехват

Комментарии к статье