«Единственный способ творить великие дела – это любить то, что ты делаешь»
JavaScript

Игра на «Морской Бой» на JavaScript: Простая Игра и Игра для Двоих


Далее на странице...

Делегирование событий в JS - что это такое?

Суть Делегирования событий заключается в следующем: если есть много похожих элементов, события на которых нужно обрабатывать также похожим/одинаковым образом, то вместо того, чтобы назначить обработчик события каждому элементу, создается один обработчик для общего родителя.

Событие делегируется - передается от родителя к дочерним элементам.



Обработчик для общего родителя

Есть несколько кнопок. Нужно, чтобы при клике по любой из них срабатывал один и тот же обработчик. Можно этот обработчик назначить отдельно для каждой кнопки. Но это не всегда удобно и правильно.

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

Исходный HTML-код

<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
   	<title>JavaScript</title>
   	<link rel="stylesheet" href="style.css">
  </head>
  <body>

    <div id="first" class="btn-block">
      <button class="blue some"></button>
      <button></button>
      <button></button>
      <button></button>
      <button></button>
      <button></button>
      <button></button>
      <button></button>
    </div>
    
	<script src="script.js"></script>
  </body>
</html>

JavaScript-код

'use strict';

// Получаем все кнопки и родительский элемент
const btns = document.querySelectorAll('button'),
      wrapper = document.querySelector('.btn-block');

// Назначаем обработчик для родителя 
// И выводим свойства элемента, на котором произошел клик    
wrapper.addEventListener('click', (event) => {
    console.dir(event.target);
});

Результат в консоли

div#first.btn-block

button
accessKey: ""
ariaAtomic: null
.....
tagName: "BUTTON"
.....

Результат в Браузере

Итак, как узнать, что клик произошел именно на кнопке, а не, например, на пустой области родителя.

1. Назначаем для родителя обработчик события. При этом передаем в стрелочную функцию объект-события.

2. Чтобы получить доступ к элементу страницы, с которым происходило взаимодействие - воспользуемся свойством target объекта Event.

3. Команда console.dir позволяет вывести свойства элемента страницы, с которым происходило взаимодействие.

Console.dir - это способ посмотреть в консоли свойства заданного JS-объекта.

console.dir(object);

4. При клике на пустой области родителя - в консоли мы увидим div#first.btn-block. То есть взаимодействие происходит с DIV-ом, укоторого id="first" и class="btn-block". Это и есть родительский элемент.

5. При клике на любой из кнопок - в консоли мы увидим button.

И если раскрыть список свойств этого элемента страницы, то свойство tagName - позволит нам понять, что взаимодействие/клик был сделан именно по кнопке: tagName: "BUTTON".

Пример делегирования событий

Выше было разобрано, как выяснить - на каком элементе произошло событие/клик: на пустой области родителя или же на одном из дочерних (отслеживаемых) элементов.

Далее делается проверка - составляется условие.

Пример 1.1

JavaScript-код

'use strict';

// Получаем все кнопки и родительский элемент
const btns = document.querySelectorAll('button'),
      wrapper = document.querySelector('.btn-block');

// Составляется условие - Если event.target существует и... 
// ... клик делается по кнопке, то... 
wrapper.addEventListener('click', (event) => {
    if (event.target && event.target.tagName == 'BUTTON'){
        console.log('Hello');
    }
});

Результат в консоли

Hello

Если клик делается именно по кнопке - то в консоли мы увидим 'Hello'. Это классический пример делегирования событий в JavaScript.

Для чего в условии прописывается event.target?

Дело в том, что в HTML не все элементы поддерживают событие "клика". Некоторые теги нельзя кликнуть и поэтому для них не будет существовать целевой элемент event.target.

Поэтому, чтобы скрипт выше всегда срабатывал - делается проверка на существование event.target.

Проверка по классу - свойство classList

Используя метод contains свойства classList можно проверить наличие класса у элемента.

Пример 1.2

JavaScript-код

'use strict';

// Получаем все кнопки и родительский элемент
const btns = document.querySelectorAll('button'),
      wrapper = document.querySelector('.btn-block');

// Делается проверка на наличие класса у элемента
wrapper.addEventListener('click', (event) => {
    if (event.target && event.target.classList.contains('blue')){
        console.log('blue');
    }
});

Результат в консоли

blue

Результат в Браузере

При клике по первой кнопке - в консоли мы увидим blue.

Итак, что такое Делегирование событий? Что при этом происходит?

Мы делегируем - передаем событие с/от родителя на его потомков.

Когда используется делегирование событий?

Для чего нужно и когда используется делегирование событий?

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

Делегирование событий стоит применять, когда приходится работать с большим кол-вом интерактивных элементов: которые могут удаляться и добавляться. 

Вернемся к нашему примеру и рассмотрим ситуацию, при которой:

1. Новая кнопка добавляется, когда используется делегирование событий, т.е. отслеживание события происходит через родителя.

2. Новая кнопка добавляется, когда обработчик события назначается для каждой кнопки отдельно - при помощи метода перебора forEach.

Новая кнопка - Делегирование событий
Пример 2.1

JavaScript-код

'use strict';

const btns = document.querySelectorAll('button'),
      wrapper = document.querySelector('.btn-block');

wrapper.addEventListener('click', (event) => {
    if (event.target && event.target.tagName == 'BUTTON'){
        console.log('Hello');
    }
});

// Создание кнопки, добавление к ней класса и вставка кнопки на страницу
const btn = document.createElement('button');
btn.classList.add('red');
wrapper.append(btn);

Результат в консоли

Hello

Результат в Браузере

Как видно из примера делегирование событий позволяет отслеживать события, когда мы имеем дело с интерактивными элементами: в нашем случае - это добавление новой кнопки. То есть обработчик срабатывает при возникновении события и на вновь появившемся элементе.

Новая кнопка - Метод перебора forEach
Пример 2.2

JavaScript-код

'use strict';

const btns = document.querySelectorAll('button'),
      wrapper = document.querySelector('.btn-block');

// Перебираем все кнопки и...
//... назначаем для каждой из них обработчик
btns.forEach( (item) => {
    item.addEventListener('click', () => {
            console.log('Hello');
    });
});
      
// Создание кнопки, добавление к ней класса и вставка кнопки на страницу
const btn = document.createElement('button');
btn.classList.add('red');
wrapper.append(btn);

Результат в Браузере

Из примера видно, что когда обработчик события назначается для каждой кнопки отдельно, то при последующем добавлении нового элемента/кнопки - обработчик не срабатывает при клике по ней.

Метод matches - Наличие класса у элемента

Выше при делегировании событий - для отслеживания события клика на дочерних элементах мы проверяли, что:

1. Клик делается по одной из кнопок - при помощи свойства tagName мы получали название тега/элемента страницы.

2. Клик делается по конкретной кнопке, у которой есть определенный класс - при этом использовался метод contains свойства classList.

Есть еще один способ отследить событие/выяснить, с каким элементом оно произошло. Это поиск по совпадению: наличие класса у определенного элемента. И это уже более продвинутое Делегирование.

Метод matches позволяет проверить, удовлетворяет ли элемент указанному CSS селектору.

элемент.matches('селектор');

Вернемся к примеру 2.1

Пример 3.1

JavaScript-код

'use strict';

const btns = document.querySelectorAll('button'),
      wrapper = document.querySelector('.btn-block');

// Отслеживаем событие на кнопке с классом 'red'
wrapper.addEventListener('click', (event) => {
    if (event.target && event.target.matches('button.red')){
        console.log('Hello');
    }
});

// Создание кнопки, добавление к ней класса и вставка кнопки на страницу
const btn = document.createElement('button');
btn.classList.add('red');
wrapper.append(btn);

Результат в Браузере

В результате обработчик срабатывает при возникновении события/при клике на кнопке с классом 'red'. event.target.matches('button.red').



Читайте также...

Отзывы и комментарии:

Комментариев нет...

Оставить отзыв:

Ваше Имя:

Текст комментария:

Ответьте на вопрос:

Сколько дней в Високосном году?


Рунет - Часть 5
Помощь сайту
Yandex-деньги/Ю-Money
410011236419322
Перевод на карту СБ
4276 1300 1671 5819
WebMoney
R711879515665 Z861169301432
Популярные заметки
Последние заметки