Stencil предоставляет механизм для работы с событиями браузера через
декоратор @Listen. Этот инструмент позволяет слушать
события, происходящие в компонентах или их родительских элементах, и
обрабатывать их внутри компонента. Важной особенностью является то, что
с помощью этого декоратора можно подписываться на события, происходящие
как внутри компонента, так и на уровне всего документа.
Декоратор @Listen используется для привязки обработчика
событий к методу компонента. Основной синтаксис следующий:
@Listen('eventName', { target: 'window' })
eventHandler(event: Event) {
// Обработчик события
}
В этом примере метод eventHandler будет вызываться
каждый раз, когда в пределах указанного элемента или области (в данном
случае, window) произойдет событие с именем
eventName.
Декоратор @Listen принимает два обязательных параметра:
имя события и объект с дополнительными опциями.
Имя события (eventName): строка,
представляющая имя события, на которое компонент будет
реагировать.
Опции: объект с конфигурацией для привязки обработчика. Основные опции:
target: указывает, на какой объект будет подписан
обработчик. Возможные значения:
'document' — для глобальных событий на уровне
документа.'window' — для событий окна.'body' — для событий, происходящих в теле
страницы.'element' — для событий внутри компонента.capture: булевое значение, определяющее, должен ли
обработчик события срабатывать на фазе захвата (по умолчанию
false).
passive: если установлено в true,
обработчик не будет блокировать прокрутку страницы.
@Component({
tag: 'my-component',
styleUrl: 'my-component.css',
shadow: true
})
export class MyComponent {
@Listen('click')
handleClick(event: MouseEvent) {
console.log('Element clicked:', event.target);
}
}
В этом примере метод handleClick будет срабатывать
каждый раз, когда на элементе компонента будет происходить событие
click.
@Component({
tag: 'my-component',
styleUrl: 'my-component.css',
shadow: true
})
export class MyComponent {
@Listen('resize', { target: 'window' })
handleResize(event: Event) {
console.log('Window resized', event);
}
}
Здесь обработчик события handleResize будет реагировать
на изменения размера окна.
Подписка на события родительских элементов: можно подписаться на события, происходящие в родительских элементах, и даже на события, происходящие на уровне документа или окна. Это дает большую гибкость для отслеживания глобальных событий, таких как прокрутка или изменение размера окна.
Удаление обработчиков: Когда компонент уничтожается, все подписки на события автоматически отменяются. Это позволяет избежать утечек памяти, не требуя вручную отсоединять обработчики.
Типы событий: обработчики могут принимать
аргумент события, который соответствует типу события, на которое
подписан компонент. Например, для события click это будет
MouseEvent, а для события resize —
Event.
Множественные обработчики: можно использовать
несколько декораторов @Listen в одном компоненте, чтобы
слушать различные события. Каждый декоратор будет связывать свой метод с
определенным событием.
Порядок обработки событий: важно учитывать, что
Stencil использует модель событий, аналогичную браузерной, с фазами
захвата и всплытия. В случае использования опции capture
обработчик будет срабатывать на фазе захвата, до того как событие
достигнет целевого элемента.
Stencil поддерживает как нативные DOM-события, так и собственные
(кастомные) события. В случае с кастомными событиями можно использовать
тот же декоратор @Listen, но с событием, которое было
создано в другом компоненте.
Пример создания кастомного события:
@Component({
tag: 'child-component',
styleUrl: 'child-component.css',
shadow: true
})
export class ChildComponent {
@Event() customEvent: EventEmitter<string>;
triggerEvent() {
this.customEvent.emit('Hello from child!');
}
}
И теперь можно прослушивать это событие в родительском компоненте:
@Component({
tag: 'parent-component',
styleUrl: 'parent-component.css',
shadow: true
})
export class ParentComponent {
@Listen('customEvent')
handleCustomEvent(event: CustomEvent) {
console.log('Received custom event:', event.detail);
}
}
В этом случае метод handleCustomEvent сработает, когда
будет выброшено событие customEvent из дочернего
компонента.
Работа с нативными и кастомными событиями: для
работы с кастомными событиями важно, чтобы событие было выброшено в
контексте DOM-дерева, которое может быть отслежено. Если событие не
относится к DOM, оно не будет перехвачено с помощью декоратора
@Listen.
Оптимизация производительности: при подписке на
глобальные события, такие как scroll или
resize, следует учитывать возможное влияние на
производительность, особенно если обработчики выполняют сложные
операции. В таких случаях рекомендуется использовать дебаунсинг или
лимитирование частоты срабатывания.
Работа с компонентами Shadow DOM: Stencil
поддерживает Shadow DOM, и это влияет на то, как события
распространяются. События, сгенерированные внутри shadow-дерева
компонента, не будут по умолчанию всплывать в родительский элемент за
пределы компонента. Однако можно настроить всплытие событий с помощью
опции bubbles при создании события.
Декоратор @Listen является мощным инструментом для
работы с событиями в Stencil, позволяя слушать как нативные события DOM,
так и кастомные события внутри компонента. Это решение облегчает процесс
подписки на события и управление ими в рамках компонентов и их иерархий,
обеспечивая высокую гибкость и масштабируемость для создания сложных
веб-приложений.