SkateJS — библиотека для создания веб-компонентов на основе
стандартов Custom Elements. Управление событиями является ключевой
частью взаимодействия компонентов друг с другом и с внешним окружением.
В SkateJS событийная модель строится поверх стандартного DOM, что
позволяет использовать привычные методы dispatchEvent и
addEventListener, но с дополнительными возможностями,
предоставляемыми самим фреймворком.
Каждый компонент SkateJS может инициировать события
с помощью метода emit. Этот метод упрощает создание и
распространение кастомных событий, обеспечивая удобный синтаксис и
автоматическое управление деталями, такими как bubbles и
composed.
Пример объявления события внутри компонента:
import { Component, h } from 'skatejs';
class MyButton extends Component {
static get is() { return 'my-button'; }
clickHandler() {
this.emit('button-clicked', { detail: { time: Date.now() } });
}
render() {
return <button oncl ick={() => this.clickHandler()}>Нажми меня</button>;
}
}
customElements.define(MyButton.is, MyButton);
Здесь событие button-clicked создается и автоматически
передается в родительский DOM. Опция detail позволяет
передавать любые данные вместе с событием.
Метод emit поддерживает несколько ключевых
параметров:
detail — объект с пользовательскими
данными, доступными через event.detail.bubbles — булево значение,
определяющее, будет ли событие всплывать по дереву DOM (по умолчанию
true).composed — определяет, будет ли
событие пересекать shadow DOM границы (по умолчанию
true).cancelable — разрешает отмену события
через event.preventDefault() (по умолчанию
false).Пример с кастомными параметрами:
this.emit('data-updated', {
detail: { value: 42 },
bubbles: true,
composed: true,
cancelable: true
});
Подписка на события в SkateJS может выполняться стандартными методами DOM:
document.querySelector('my-button').addEventListener('button-clicked', (event) => {
console.log('Событие произошло в', event.detail.time);
});
Также можно использовать реактивные свойства компонента и методы SkateJS для автоматической реакции на изменения и события, что особенно полезно при построении сложных UI-компонентов.
SkateJS полностью совместим с Shadow DOM. При этом важно учитывать, что событие должно быть композируемым, чтобы его можно было отловить вне теневого корня:
this.emit('shadow-event', { composed: true });
Без composed: true событие останется внутри shadow root
и не будет доступно внешнему DOM.
Метод emit в SkateJS является оберткой над стандартным
CustomEvent. Это позволяет писать компактный код без
необходимости вручную создавать объекты CustomEvent. Пример
сравнения:
Стандартный подход:
const event = new CustomEvent('button-clicked', {
detail: { time: Date.now() },
bubbles: true,
composed: true
});
this.dispatchEvent(event);
С SkateJS:
this.emit('button-clicked', { detail: { time: Date.now() } });
Синтаксис SkateJS сокращает количество кода, улучшает читаемость и стандартизирует обработку событий внутри компонентов.
composed: true, если событие должно
быть доступно за пределами Shadow DOM.mousemove или input) лучше использовать
стандартные события DOM, чтобы избежать лишней нагрузки.my-button-clicked), чтобы исключить коллизии имен.import { Component, h } from 'skatejs';
class Counter extends Component {
static get is() { return 'my-counter'; }
static get props() {
return {
count: { attribute: true, type: Number }
};
}
increment() {
this.count++;
this.emit('count-changed', { detail: { count: this.count } });
}
render() {
return (
<div>
<span>{this.count}</span>
<button oncl ick={() => this.increment()}>+</button>
</div>
);
}
}
customElements.define(Counter.is, Counter);
В этом примере компонент Counter уведомляет внешний код
о каждом изменении счётчика через событие count-changed.
Внешний DOM может реагировать на него следующим образом:
document.querySelector('my-counter').addEventListener('count-changed', (event) => {
console.log('Текущее значение:', event.detail.count);
});
emit.detail.CustomEvent.Эта система позволяет строить реактивные и модульные компоненты, где внутренние события легко интегрируются с внешними обработчиками, а управление DOM остаётся полностью предсказуемым и стандартным.