Преобразуем метод jQuery click() в Vanilla JS

Добрый день!

Сегодня мы разберем, как преобразовать метод jQuery click() в обычный JS.

Что делает метод jQuery click()

Метод click() перехватывает нажатие на элементы с совпавшим селектором и выполняет функцию callback, которую мы ему передали. Это очень удобный метод, который делает почти то же самое, что и on(‘click’):

// Обработчик запустится, когда мы кликнем по элементу с классом click-me
$('.click-me').click(function (event) {
	// Выполнить колбэк...
});

// Обработчик запустится, когда мы кликнем по элементу с классом click-me
$('.click-me').on('click', function (event) {
	// Выполнить колбэк...
});

Теперь преобразуем это в Vanilla JS.

Эквивалентный метод click() в Vanilla JS.

У Vanilla JS есть метод addEventListener(), который прослушивает события для элемента.

// Выбираем элемент .click-me
var clickMe = document.querySelector('.click-me');

// Добавляем обработчик клика для элемента .click-me
clickMe.addEventListener('click', function (event) {
	// Что-то сделать...
});

Одно проблема. Код выше запустится только для первого элемента click-me.

К сожалению, мы не можем вызвать addEventListener() для группы элементов.

// Получить все .click-me элементы
var clickMeAll = document.querySelectorAll('.click-me');

// Это НЕ будет работать
clickMeAll.addEventListener('click', function (event) {
	// Что-то сделать...
});

Что мы можем сделать вместо этого?

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

Техника делегирования событий позволит перехватывать все события определенного типа для родительского элемента.

Мы будем перехватывать все события click для элемента document. И проигнорируем все события, которые сработали на элементах, у которых класс не .click-me.

Мы можем использовать event.target, чтобы получить элемент, на котором произошел клик. Далее с помощью метода matches() проверим класс элемента.

// Прослушиваем все события для document
document.addEventListener('click', function (event) {

	// Если элемент не содержит класс .click-me, то игнорируем его
	if (!event.target.matches('.click-me')) return;

	// Иначе делаем что-нибудь с элементом...
});

Все отлично, но что будет, если в элементе с классом click-me есть еще элементы внутри?

<button class="click-me">
	Click Me Please
	<span>You won't regret it</span>
</button>

Здесь, если мы кликнем по тексту в span «You won’t regret it», то обработчик проигнорирует нажатие, так как оно произошло не на элементе с классом click-me.

Что мы можем сделать?

Метод closest() работает, как и matches(). Но вместо того, чтобы проверять, соответствует ли элемент селектору, он также проверяет, соответствует ли какой-либо родительский элемент этому селектору.

 // Прослушиваем все события для document
document.addEventListener('click', function (event) {

	// Если кликнутый элементы не содержит класс click-me и не окружен элементом с классом click-me
  	// тогда игнорируем этот элемент
	if (!event.target.closest('.click-me')) return;

	// Иначе делаем что-нибудь с элементом...
});

Теперь все работает, как надо!

Поддержка браузерами

Метод addEventListener() отлично работает в современных браузерах вплоть до IE9.

Matches() работает в современных браузерах, но для IE понадобится полифил. Closest() так же требует полифил для IE.


Оригинал статьи: ссылка
Автор статьи: Alex. Категория: JavaScript
Дата публикации: 27.11.2020