← Назад к вопросам

Делал ли кастомный Event в браузере

2.0 Middle🔥 121 комментариев
#JavaScript Core

Комментарии (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
  • Разделения ответственности в коде

Научись использовать их для гибкой архитектуры и слабой связанности компонентов!

Делал ли кастомный Event в браузере | PrepBro