Как заставить веб-компоненты общаться (часть 1)
Глупый веб-компонент
Для этой статьи создадим довольно бессмысленный веб-компонент <wc-highlight>.
<wc-highlight>
<div>1</div>
<div>2</div>
<div>3</div>
</wc-highlight>Когда веб-компонент инстанцируется, он…
- Получает всех непосредственных потомков
.childrenвнутри себя. - Устанавливает первый элемент в этом списке (с индексом
0) в качестве активногоactive. - Выделите первый элемент в коллекции, установив
[aria-selected='true'].
customElements.define('wc-highlight', class extends HTMLElement {
/**
* Создание элемента
*/
constructor () {
// Всегда вызывайте super первым в конструкторе
super();
// Определяем свойства
this.boxes = Array.from(this.children);
this.active = 0;
// Устанавливаем [aria-selected]
// Если первый элемент, устанавливаем в true
// Иначе, устанавливаем в false
this.boxes.forEach(function (box, index) {
box.setAttribute('aria-selected', index === 0 ? true : false);
});
}
});Также в веб-компоненте есть метод .next().
Он увеличивает значение this.active на 1 (и сбрасывает его на 0, когда достигает конц списка). Затем он обновляет атрибут [aria-selected], чтобы выделить новый элемент.
/**
* Перейти к следующему элементу
*/
next () {
// Кэшируем активный, в данный момент, индекс
let current = this.active;
// Обновляем активный индекс
this.active++;
// Если это конец, возвращаемся к началу.
if (this.active === this.boxes.length) {
this.active = 0;
}
// Обновляем [aria-selected]
this.boxes[current].setAttribute('aria-selected', false);
this.boxes[this.active].setAttribute('aria-selected', true);
}Запустив его на элементе <wc-highlight>, можно перенести выделение с текущего элемента на следующий в списке.
let highlight = document.querySelector('wc-highlight');
highlight.next();Вкладываем веб-компонент внутрь него
Для такого простого веб-компонента я обычно использую элементы управления для перехода к следующему элементу как часть компонента.
Но в крупных проектах может быть удобно иметь ряд небольших, но взаимосвязанных компонентов, каждый из которых обрабатывает один небольшой фрагмент пользовательского интерфейса и взаимодействует с другими компонентами.
В целях обучения создадим элемент <wc-highlight-controls> внутри constructor() веб-компонента <wc-highlight> и внедрим его в DOM.
/**
* Создание элемента
*/
constructor () {
// ...
this.boxes.forEach(function (box, index) {
box.setAttribute('aria-selected', index === 0 ? true : false);
});
// Append controls
let controls = document.createElement('wc-highlight-controls');
this.append(controls);
}Затем можно определить <wc-highlight-controls> как отдельный веб-компонент.
customElements.define('wc-highlight-controls', class extends HTMLElement {
/**
* Создание элемента
*/
constructor () {
// Всегда вызывайте super первым в конструкторе
super();
// Код компонента...
}
});Внутри constructor() можно использовать метод Element.closest(), для получения родительского элемента <wc-highlight>, и присвоить его this.highlight.
Если родительский элемент не найден, завершаем выполнение с помощью return.
/**
* Создание элемента
*/
constructor () {
// Всегда вызывайте super первым в конструкторе
super();
// Получаем родительский элемент <wc-highlight>
this.highlight = this.closest('wc-highlight');
if (!this.highlight) return;Далее создадим элемент button, зададим ему текст и .append() его внутри веб-компонента.
Затем добавим к нему слушателя события click.
/**
* Создание элемента
*/
constructor () {
// Всегда вызывайте super первым в конструкторе
super();
// Получаем родительский элемент <wc-highlight>
this.highlight = this.closest('wc-highlight');
if (!this.highlight) return;
// Создаём кнопку button
this.button = document.createElement('button');
this.button.textContent = 'Next';
this.append(this.button);
// Слушаем событие clicks для кнопки button
this.button.addEventListener('click', this);
}Внутри метода handleEvent() запускаем метод .next() на this.highlight, для перехода к следующему элементу.
/**
* Обработка событий
* @param {Event} event Объект события
*/
handleEvent (event) {
this.highlight.next();
}Это очень простое подключение
Этот метод основан на тесном взаимодействии элементов DOM.
Он работает, но может быть ненадёжным, поскольку зависит от того, что определённые элементы загружаются в правильном порядке и всегда имеют доступ друг к другу.
Завтра рассмотрим предпочитаемый мною метод: Пользовательские события / Custom Events.
Они дают возможность настраивать веб-компоненты и обмениваться данными более гибким и независимым способом.
Они также позволяют разработчикам расширять веб-компонент способами, о которых при его создании вы, возможно, не подумали или не захотели их поддерживать напрямую.
Все статьи серии о Веб-Компонентах/Web Component
- Ваш первый веб-компонент
- Добавление опций в веб-компонент
- Улучшение веб-компонента
- Различные способы инстанцирования веб-компонента
- Методы жизненного цикла веб-компонента
- Как обнаружить изменение атрибутов веб-компонента
- Как заставить веб-компоненты общаться (часть 1)
- Как заставить веб-компоненты общаться (часть 2)