Как заставить веб-компоненты общаться (часть 2)
Пользовательские события
Метод new CustomEvent()
создаёт объект пользовательского события, которое можно инициировать на определённом элементе.
Передайте тип события в качестве аргумента. В качестве второго аргумента можно указать объект, содержащий подробную информацию о том, является ли событие bubbles
(распространяемым), cancelable
(отменяемым), и любые detail
(детали), которыми хотите поделиться.
Затем запускаете метод dispatchEvent()
на элементе, передавая событие в качестве аргумента.
// Создаём новое событие
let event = new CustomEvent(`my-event`, {
bubbles: true,
cancelable: true,
detail: 'Hi there!'
});
// Передаём событие
let elem = document.querySelector('#app');
elem.dispatchEvent(event);
Затем можно прослушать это событие с помощью метода Element.addEventListner()
, как и любое другое событие.
elem.addEventListener('my-event', function (event) {
console.log(event.detail);
});
Существует множество различных соглашений об именовании, но для библиотечных событий я предпочитаю использовать шаблон {library-name}:{event-type}
.
Например, я назову событие, возникающее при нажатии кнопки Next в веб-компоненте <wc-highlight-controls>
— highlight-controls:next
.
Создание события веб-компонента
Давайте заменим в веб-компоненте <wc-highlight-controls>
this.highlight.next()
в методе handleEvent()
на пользовательское событие.
/**
* Обработка событий
* @param {Event} event Объект события
*/
handleEvent (event) {
// Создаём новое событие
let next = new CustomEvent('highlight-controls:next', {
bubbles: true
});
// Отправляем событие
this.dispatchEvent(next);
}
Также можно удалить this.highlight
из constructor()
, поскольку он больше не нужен.
Вернувшись в веб-компонент <wc-highlight>
, можно прослушивать событие highlight-controls:next
внутри constructor()
. Благодаря тому, что события распространяются, можно прослушивать непосредственно наш элемент и перехватывать любые события, происходящие в нем.
/**
* Создание элемента
*/
constructor () {
// ...
// Добавляем controls
let controls = document.createElement('wc-highlight-controls');
this.append(controls);
// Слушаем событие highlight-controls:next
this.addEventListener('highlight-controls:next', this);
}
Затем обработаем событие, выполнив this.next()
.
/**
* Обработка событий
* @param {Event} event Объект события
*/
handleEvent (event) {
this.next();
}
Щедро используйте события
Если бы я создавал это как реальный веб-компонент, я бы, вероятно, эмитировал событие highlight:next
внутри метода .next()
для веб-компонента <wc-highlight>
.
Я бы включил в details
свойства current
и this.active
, а также количество всех блоков. Это событие может быть использовано другими веб-компонентами, которые может создать разработчик.
/**
* Перейти к следующему элементу
*/
next () {
// ...
// Обновляем [aria-selected]
this.boxes[current].setAttribute('aria-selected', false);
this.boxes[this.active].setAttribute('aria-selected', true);
// Создаём новое событие
let next = new CustomEvent('highlight:next', {
bubbles: true,
detail: {
current,
next: this.active,
boxes: this.boxes
}
});
// Отправляем событие
this.dispatchEvent(next);
}
Например, это можно использовать для создания дополнительного пользовательского интерфейса, отображающего номер текущего выделенного блока, например 1 из 3.
Все статьи серии о Веб-Компонентах/Web Component
- Ваш первый веб-компонент
- Добавление опций в веб-компонент
- Улучшение веб-компонента
- Различные способы инстанцирования веб-компонента
- Методы жизненного цикла веб-компонента
- Как обнаружить изменение атрибутов веб-компонента
- Как заставить веб-компоненты общаться (часть 1)
- Как заставить веб-компоненты общаться (часть 2)