На прошлом уроке мы научились вешать обработчик события на одну кнопку в JS . Однако методы, хорошо работающие с единичными объектами, совершенно не эффективны для массовых манипуляций. Пример из реальной жизни: Директор школы не подходит к каждому новому ученику, чтобы сообщить ему о школьных правилах. Эту почетную...

Делегирование событий в JS

На прошлом уроке мы научились вешать обработчик события на одну кнопку в JS. Однако методы, хорошо работающие с единичными объектами, совершенно не эффективны для массовых манипуляций. Пример из реальной жизни: Директор школы не подходит к каждому новому ученику, чтобы сообщить ему о школьных правилах. Эту почетную миссию он делегирует классному руководителю, чтобы каждый новый ученик знал общие правила.

На странице имеется какое-то количество навигационных ссылок, на которых при клике будут срабатывать одинаковые события. Навесить на каждую кнопку по событию не так и сложно. Но есть одна проблема. А что если пользователь сайта (заказчик) добавит через админку новую ссылку. У добавленной ссылки уже не будет события. Делегирование событий обезопасит вас от подобных косяков. Правильно будет работать сразу с родительским элементом, а не с каждым дочерним по отдельности. Тогда каждый новый добавленный элемент в родительский блок, автоматически унаследует и его событие.

Пример с делегированием в JS

Перед нами обычный список, где теги li являются дочерними для тега ul. Мы будем работать с родителем всех li.

<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>

Для начала нужно получить данные для работы - оба элемента. Родителя мы получаем с помощью метода querySelector, а его детей - через querySelectorAll. В чем разница? Первый метод получает только один единственный элемент. А для получения группы одинаковых элементов, применяют второй метод.

let ul = document.querySelector('ul');
    li = document.querySelectorAll('li');

Навешиваем обработчик события addEventListener на родителя и первым параметром передаем событие клик (можно любое событие). Вторым параметром передаем callback функцию с передаваемым объектом события (event), чтобы свойства объекта могли вызываться внутри, функции и выведем их в консоль. Нас интересует, как в DOM прописано значение у свойства tagName.

ul.addEventListener('click', function(event){
    console.log(event);
});

Свойства выведутся в консоль при клике по списку. Раскрываем всю эту цепочку MouseEvent → target → tagName. Дословный перевод: событие мыши → цель → имя тега. Начинающие разработчики часто заглядывают в консоль, поскольку визуализируя процесс, проще понять смысл происходящего и увидеть ошибки.

Делегирование событий в JS.

Суть делегирования событий

Нам нужно проверить, куда кликнул пользователь, если он кликнул по списку, то выполнится какое-то действие.

if(event.target && event.target.tagName == 'LI'){
    console.log('Привет!')
}

Нас не интересуют только клики по пунктам списка. Если целью события клика event, оказался тег LI, то в консоль выведется слово Привет!

В первой части условия event.target мы проверяем, есть ли у объекта события свойство target. Во второй части условия, после оператора AND, мы проверяем, а действительно ли кликнули по тегу li.

Делегирование событий в JS.

Если элемент подходит под условие, то на нем сработает та функция (набор действий), которую мы укажем в теле. Теперь при добавлении новых пунктов меню, можно не беспокоиться, что они не будут реагировать на события.

Пример кода целиком.

let ul = document.querySelector('ul');
    li = document.querySelectorAll('li');

ul.addEventListener('click', function(event){
    if(event.target && event.target.tagName == 'LI'){
        console.log('Привет!')
    }
});

Делегирование событий в JS, нужно обязательно применять, если на странице есть много элементов с одним и тем же обработчиком события.

Всплытие событий в JS

Вам не кажется странным, что мы кликнули по ul, а событие сработало на li? Так произошло, благодарю понятию - всплытия событий. Принцип всплытия заключается в том, что когда кликают по элементу, то сначала обработчик срабатывает на самом нижнем вложенном элементе в иерархии DOM структуры.