Кратко
CustomEvent — собственный тип события, который вы создаёте. detail — произвольные данные, передаваемые с событием. dispatchEvent() отправляет событие на элемент. addEventListener() слушает его. Это позволяет компонентам общаться без прямых зависимостей.
Подробно
Создание: const event = new CustomEvent('user-login', { detail: { username: 'Анна', role: 'admin' } });
Отправка: document.dispatchEvent(event);
Прослушивание: document.addEventListener('user-login', (e) => { console.log('Вошёл:', e.detail.username); console.log('Роль:', e.detail.role); });
detail — произвольные данные (объект, массив, строка, число).
Пример: компонент модалки
class Modal { constructor(element) { this.element = element; this.element.addEventListener('close', () => { this.hide(); }); }
hide() { this.element.style.display = 'none'; // Уведомляем другие компоненты this.element.dispatchEvent(new CustomEvent('modal-closed', { detail: { modalId: this.element.id } })); } }
// Другой компонент реагирует
document.addEventListener('modal-closed', (e) => {
console.log(Модалка ${e.detail.modalId} закрыта);
});
События на конкретном элементе (не document):
const button = document.querySelector('#myButton'); button.addEventListener('my-custom-event', handler); button.dispatchEvent(new CustomEvent('my-custom-event', { detail: 42 }));
Ментальная модель
CustomEvent — как внутренняя переговорная комната. Вы создаёте свою «тему разговора» (тип события), передаёте «досье» (detail), и отправляете его (dispatchEvent). Любой, кто «слушает эту частоту» (addEventListener), получит сообщение. Компоненты общаются, не зная друг о друге напрямую.
Примеры
**Самый простой:**
// Создаём и отправляем событие
const event = new CustomEvent('greet', {
detail: { name: 'Мир' }
});
document.dispatchEvent(event);
// Слушаем
document.addEventListener('greet', (e) => {
console.log(`Привет, ${e.detail.name}!`);
});
// Вывод: Привет, Мир!Простейший custom event: создаём, отправляем, слушаем.
**Простой:**
// Компонент корзины
class Cart {
constructor() {
this.items = [];
}
addItem(item) {
this.items.push(item);
// Уведомляем UI
document.dispatchEvent(new CustomEvent('cart-updated', {
detail: { items: this.items, total: this.items.length }
}));
}
}
// UI реагирует
document.addEventListener('cart-updated', (e) => {
document.querySelector('.cart-count').textContent = e.detail.total;
});
const cart = new Cart();
cart.addItem({ name: 'Товар 1' }); // UI обновляется автоматическиReal-world: компонент корзины уведомляет UI через custom events.
**Реальный пример:**
// Система уведомлений
class NotificationService {
static notify(message, type = 'info') {
document.dispatchEvent(new CustomEvent('notification', {
detail: { message, type, timestamp: Date.now() }
}));
}
}
// Слушатели
document.addEventListener('notification', (e) => {
const { message, type } = e.detail;
console.log(`[${type.toUpperCase()}] ${message}`);
});
NotificationService.notify('Загрузка...', 'info');
NotificationService.notify('Ошибка!', 'error');Сервис уведомлений: несколько компонентов могут отправлять и слушать.
Частые ошибки
**Неправильно:** Отправлять custom event без detail
**Почему:** detail не обязателен, но без него событие бесполезно — нет данных для передачи.
**Правильно:** Передавайте через detail только то, что нужно слушателям.
**Неправильно:** Думать, что custom events — это замена для callback
**Почему:** Custom events — для общения между отдалёнными компонентами. Прямые callback'и проще для простых случаев.
**Правильно:** Пользовательские события (custom events) — слабая связь (loosely coupled): отправитель не знает, кто слушает. Колбэки (callbacks) — прямая связь: вызывающий передаёт функцию напрямую.
**Неправильно:** Забывать, что dispatchEvent синхронный
**Почему:** dispatchEvent вызывает все listener'ы синхронно (в том же потоке).
**Правильно:** Custom events обрабатываются синхронно, как и встроенные.
Важно запомнить
- new CustomEvent('type', { detail: data }) — создание
- element.dispatchEvent(event) — отправка
- element.addEventListener('type', handler) — прослушивание
- e.detail — данные события
- Custom events обрабатываются синхронно
Связь
Назад: Вы умеете слушать события (DA1-DA4). Теперь вы можете создавать собственные типы событий.
Вперёд: Следующий урок (DA6) — события мыши и Drag and Drop API.