Как прослушивать несколько событий в веб-компоненте

Источник: «How to listen to multiple events in a Web Component with the handleEvent() method»
В предыдущей статье я писал о методе handleEvent() для работы со слушателями событий в веб-компонентах. Сегодня поговорим о том, как использовать его для обработки нескольких типов событий.

Образец веб-компонента

Представим, что у нас есть веб-компонент <mirror-type>. Внутри него есть <input> и <button>.

Когда пользователь печатает в <input>, необходимо отображать набранный текст в div (внедрённый при загрузке веб-компонента). Когда он нажимает <button>, необходимо очистить ввод и отображаемый текст.

<mirror-type>
<label for="msg">Type some stuff</label>
<input type="text" id="msg">
<button>Clear</button>
</mirror-type>

Создание веб-компонента

Давайте начнём создание веб-компонента.

Определим свойства this.input и this.button для существующего HTML. Также создадим элемент this.mirror и внедрим его в DOM.

(Если вы не уверены в том, что здесь происходит, рекомендую прочитать статью "Ваш первый веб-компонент" в качестве основы.)

customElements.define('mirror-type', class extends HTMLElement {

/**
* Инстанцирование компонент
*/

constructor () {

// Доступ к свойствам родительского класса
super();

// Определение свойств
this.input = this.querySelector('input');
this.button = this.querySelector('button');
this.mirror = document.createElement('div');

// Внедрение элемента mirror в DOM
this.append(this.mirror);

}

});

Теперь можно добавить интерактивности.

Зеркалирование ввода

Внутри constructor() будем слушать события input на this.input и запускать метод handleEvent() в ответ.

constructor () {

// ...

// Внедрение элемента mirror в DOM
this.append(this.mirror);

// Прослушивание событий
this.input.addEventListener('input', this);

}

/**
* Обработка событий
* @param {Event} event Объект события
*/

handleEvent (event) {
// Обработка...
}

Внутри метода handleEvent() обновляем .textContent в this.mirror, чтобы он соответствовал this.input.value.

/**
* Обработка событий
* @param {Event} event Объект события
*/

handleEvent (event) {
this.mirror.textContent = this.input.value;
}

See the Pen

Очистка ввода

Теперь, допустим, нужно всё очистить при нажатии кнопки this.button.

Начнём с добавления события click для this.button.

// Прослушивание событий
this.input.addEventListener('input', this);
this.button.addEventListener('click', this);

Но как обработать оба типа событий в методе handleEvent()?

Можно использовать выражение if...else.

/**
* Обработка событий
* @param {Event} event Объект события
*/

handleEvent (event) {
if (event.type === 'input') {
this.mirror.textContent = this.input.value;
} else {
this.input.value = '';
this.mirror.textContent = '';
}
}

Но по мере масштабирования веб-компонента и роста количества слушателей управлять этим станет сложновато.

Поскольку класс веб-компонента является объектом, можно использовать скобочную нотацию для запуска его методов. Мне нравится создавать методы on*() для каждого события и использовать event.type в методе handleEvent() для их автоматического запуска.

/**
* Обработка событий
* @param {Event} event Объект события
*/

handleEvent (event) {
this[`on${event.type}`](event);
}

/**
* Обработка событий input
*/

oninput () {
this.mirror.textContent = this.input.value;
}

/**
* Обработка событий click
*/

onclick () {
this.input.value = '';
this.mirror.textContent = '';
}

See the Pen

Хотя он немного более многословен, но по мере роста количества событий им легче управлять и поддерживать веб-компонент.

Все статьи серии о Веб-Компонентах/Web Component

Дополнительные материалы

Предыдущая Статья

Появится ли в PHP 8.4 инстанцирование класса без лишних скобок

Следующая Статья

Введение в JavaScript Proxy