Всплытие событий

В FAST Element события в DOM управляются по тем же принципам, что и в стандартном HTML, однако библиотека добавляет удобные механизмы для работы с кастомными событиями, обеспечивая их интеграцию с компонентной моделью. Понимание всплытия событий и особенностей их обработки является ключевым для построения реактивных интерфейсов.


Основы событийного механизма

Каждое событие в FAST Element наследует поведение стандартного DOM-события. Основные свойства событий:

  • type — тип события (например, click, change, custom-event).
  • bubbles — логическое значение, указывающее, будет ли событие всплывать вверх по дереву DOM. По умолчанию кастомные события в FAST Element не всплывают, если не указано bubbles: true.
  • composed — определяет, может ли событие пересекать границы Shadow DOM. Если composed: false, событие ограничено текущим Shadow DOM.
  • detail — дополнительная информация, передаваемая в кастомном событии.

Пример создания кастомного события:

this.dispatchEvent(new CustomEvent('item-selected', {
  bubbles: true,
  composed: true,
  detail: { id: 42 }
}));

В этом примере событие item-selected всплывает по дереву компонентов и выходит за границы Shadow DOM, передавая объект { id: 42 } в обработчик.


Всплытие событий в компонентной иерархии

FAST Element активно использует Shadow DOM, поэтому важно различать два уровня всплытия:

  1. Внутри Shadow DOM компонента — событие проходит через локальные узлы и может быть перехвачено внутренними обработчиками.
  2. На уровне внешнего DOM — событие должно иметь composed: true, чтобы выйти из Shadow DOM и быть доступным родительскому компоненту или документу.

Обработчик на родительском элементе:

const parent = document.querySelector('parent-component');
parent.addEventListener('item-selected', event => {
  console.log(event.detail.id); // 42
});

Если свойство composed не установлено, событие останется скрытым внутри Shadow DOM и не будет перехвачено этим обработчиком.


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

FAST Element позволяет использовать делегирование событий через шаблонное связывание. Атрибут @event на элементе в шаблоне автоматически подписывает компонент на указанное событие:

html`<button @click="${this.handleClick}">Нажми</button>`

При этом handleClick вызывается только для конкретного элемента, но при необходимости можно реализовать делегирование через общий родительский элемент, обрабатывая события всех потомков:

parent.addEventListener('click', event => {
  if(event.target.matches('button.child')) {
    this.onChildButtonClick(event);
  }
});

Такой подход снижает количество подписок на события и упрощает управление динамическими элементами.


Особенности кастомных событий в FAST Element

  1. Автоматическая генерация событий через Observable свойства. Любое свойство компонента, помеченное как @observable, может генерировать события изменения, которые можно использовать для реактивной логики.
  2. События жизненного цикла компонентаconnectedCallback, disconnectedCallback, attributeChangedCallback. Эти события позволяют отслеживать подключение компонента к DOM и изменения атрибутов.
  3. Влияние на слоты и контент — при использовании <slot> событие может быть перехвачено внутри слота, если оно имеет composed: true. В противном случае слоты будут “изолированы” от событий внешнего DOM.

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

@observable selectedItem;

selectedItemChanged(oldValue, newValue) {
  this.dispatchEvent(new CustomEvent('selected-item-changed', {
    bubbles: true,
    composed: true,
    detail: { oldValue, newValue }
  }));
}

Это позволяет любому родительскому компоненту реагировать на изменения состояния дочернего компонента через единый интерфейс событий.


Контроль всплытия и предотвращение стандартного поведения

FAST Element поддерживает стандартные методы stopPropagation и preventDefault, позволяя точно контролировать поведение событий:

handleClick(event) {
  event.stopPropagation(); // предотвращает дальнейшее всплытие
  event.preventDefault();  // предотвращает стандартное поведение, например переход по ссылке
}

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


Практические рекомендации

  • Всегда указывать bubbles: true и composed: true для кастомных событий, если требуется, чтобы они были видны родительскому компоненту.
  • Использовать делегирование для динамически создаваемых элементов вместо подписки на каждый элемент отдельно.
  • Применять stopPropagation только при явной необходимости, чтобы не нарушить работу других компонентов.
  • Связывать события с @observable свойствами для реактивной архитектуры, обеспечивая чистое отделение состояния от UI.

Всплытие событий в FAST Element — это гибкий инструмент для построения компонентной логики, который сочетает стандартный DOM-механизм с особенностями Shadow DOM и реактивными свойствами компонентов. Правильное использование этих возможностей обеспечивает надежное взаимодействие компонентов и чистую архитектуру приложений.