Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Делал ли кастомный Event в браузере
Custom Event (кастомное событие) — это событие, созданное разработчиком вручную, которое работает так же, как встроенные события браузера (click, submit, load и т.д.). Это мощный инструмент для взаимодействия между компонентами и архитектуры приложения.
Что такое Custom Event?
Custom Event — это объект, который можно:
- Создавать с произвольным названием
- Передавать данные через объект деталей
- Распространять (dispatch) на элементы DOM
- Слушать (addEventListener) в других частях кода
Основной синтаксис
// Создание Custom Event
const customEvent = new CustomEvent('myEvent', {
detail: { message: 'Hello from custom event' },
bubbles: true, // Событие поднимается вверх по DOM
cancelable: true // Событие можно отменить
});
// Отправка события
element.dispatchEvent(customEvent);
Полный пример использования
// Компонент 1: создаёт и отправляет событие
class UserComponent {
handleUserLogin(user) {
// Кастомное событие при логине
const event = new CustomEvent('userLoggedIn', {
detail: { userId: user.id, username: user.name },
bubbles: true
});
document.dispatchEvent(event);
}
}
// Компонент 2: слушает событие
class NotificationComponent {
constructor() {
document.addEventListener('userLoggedIn', (event) => {
console.log(`Пользователь ${event.detail.username} вошёл`);
this.showNotification(`Добро пожаловать, ${event.detail.username}!`);
});
}
showNotification(message) {
// Отобразить уведомление
}
}
Синтаксис Event вместо CustomEvent
Можно также использовать более общий конструктор Event (но без деталей):
// Способ 1: CustomEvent (рекомендуется)
const event1 = new CustomEvent('myEvent', {
detail: { data: 'some value' }
});
// Способ 2: Event с методом initEvent (устаревший, не рекомендуется)
const event2 = new Event('myEvent', { bubbles: true });
// Но передать данные нельзя напрямую
Практический пример: форма с валидацией
class FormValidator {
constructor(formElement) {
this.form = formElement;
this.form.addEventListener('submit', (e) => this.handleSubmit(e));
}
handleSubmit(e) {
e.preventDefault();
const formData = new FormData(this.form);
const data = Object.fromEntries(formData);
if (this.validate(data)) {
// Отправить кастомное событие об успешной валидации
const validEvent = new CustomEvent('formValid', {
detail: { formData: data },
bubbles: true,
cancelable: true
});
this.form.dispatchEvent(validEvent);
console.log('Форма валидна!');
} else {
// Отправить событие об ошибке
const errorEvent = new CustomEvent('formInvalid', {
detail: { errors: this.getErrors() },
bubbles: true
});
this.form.dispatchEvent(errorEvent);
}
}
validate(data) {
return data.email && data.email.includes('@');
}
getErrors() {
return ['Email не заполнен или невалиден'];
}
}
// Использование:
const form = document.querySelector('#myForm');
const validator = new FormValidator(form);
form.addEventListener('formValid', (e) => {
console.log('Данные валидны:', e.detail.formData);
// Отправить на сервер
});
form.addEventListener('formInvalid', (e) => {
console.log('Ошибки:', e.detail.errors);
// Показать ошибки пользователю
});
Custom Event в React
// Компонент, который отправляет событие
function UserLoginForm() {
const handleLogin = (user) => {
const event = new CustomEvent('userLogin', {
detail: { user },
bubbles: true
});
window.dispatchEvent(event);
};
return <button onClick={() => handleLogin({ id: 1, name: 'John' })}>Login</button>;
}
// Хук для прослушивания Custom Event
function useCustomEvent(eventName) {
const [data, setData] = React.useState(null);
React.useEffect(() => {
const handleEvent = (e) => {
setData(e.detail);
};
window.addEventListener(eventName, handleEvent);
return () => window.removeEventListener(eventName, handleEvent);
}, [eventName]);
return data;
}
// Использование в другом компоненте
function NotificationCenter() {
const loginData = useCustomEvent('userLogin');
return loginData ? <p>Вошёл: {loginData.user.name}</p> : null;
}
Отмена Custom Event
Если событие создано с cancelable: true, его можно отменить:
const event = new CustomEvent('payment', {
detail: { amount: 100 },
cancelable: true
});
element.addEventListener('payment', (e) => {
if (e.detail.amount > 50) {
e.preventDefault(); // Отменить событие
console.log('Платёж отклонен');
}
});
// Проверить, было ли отменено
const wasPreventedDefault = !element.dispatchEvent(event);
console.log('Событие отменено:', wasPreventedDefault);
Распространение событий (Event Bubbling)
const parent = document.querySelector('#parent');
const child = document.querySelector('#child');
// Событие с bubbles: true будет подниматься к родителю
const event = new CustomEvent('myEvent', { bubbles: true });
parent.addEventListener('myEvent', () => console.log('Поймано на родителе'));
child.dispatchEvent(event); // Выведет: "Поймано на родителе"
// С bubbles: false событие не поднимется
const nonBubblingEvent = new CustomEvent('myEvent', { bubbles: false });
child.dispatchEvent(nonBubblingEvent); // Ничего не произойдёт
Когда использовать Custom Event
Хорошие сценарии:
- Коммуникация между компонентами (особенно когда нет общего родителя)
- Плагины и расширения (разделённый код)
- Глобальные уведомления (пользователь вошёл, данные загружены)
- Pub/Sub паттерн (издатель-подписчик)
Когда не использовать:
- Простая передача props в React — используй state
- Синхронизация между компонентами — используй context или state management
- Частые обновления — пускай работает медленнее, чем прямые обновления
Best Practice для Custom Event
// Создай утилиту для работы с событиями
class EventBus {
static emit(eventName, detail) {
const event = new CustomEvent(eventName, { detail, bubbles: true });
window.dispatchEvent(event);
}
static on(eventName, callback) {
window.addEventListener(eventName, callback);
}
static off(eventName, callback) {
window.removeEventListener(eventName, callback);
}
}
// Использование:
EventBus.emit('userLoggedIn', { userId: 123 });
EventBus.on('userLoggedIn', (e) => console.log(e.detail));
Итог
Custom Event — это мощный инструмент для:
- Создания событий с произвольным названием
- Передачи данных между компонентами
- Реализации паттерна pub/sub
- Разделения ответственности в коде
Научись использовать их для гибкой архитектуры и слабой связанности компонентов!