Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds

Własne wydarzenia (Custom Events)

W Parku Jurajskim różne systemy muszą ze sobą współpracować - system monitoringu dinozaurów musi informować centrum bezpieczeństwa o zagrożeniach, a centrum bezpieczeństwa musi powiadomić ekipy ratunkowe. Standardowe wydarzenia przeglądarki (click, keydown, submit) obsługują interakcje użytkownika, ale co jeśli potrzebujemy własnych komunikatów między modułami aplikacji? Tutaj z pomocą przychodzą Custom Events - własne, niestandardowe wydarzenia.

Tworzenie CustomEvent

Konstruktor

CustomEvent
pozwala stworzyć wydarzenie o dowolnej nazwie i przekazać dodatkowe dane przez właściwość
detail
:

1// Składnia: new CustomEvent(nazwaWydarzenia, opcje)
2const alertEvent = new CustomEvent('dinoAlert', {
3  detail: {
4    species: 'Velociraptor',
5    zone: 'B6',
6    threatLevel: 9
7  },
8  bubbles: true,      // Czy wydarzenie bąbelkuje w górę drzewa DOM
9  cancelable: true     // Czy można je anulować przez preventDefault()
10});

Właściwość

detail
może zawierać dowolne dane - obiekty, tablice, stringi, liczby. To główna różnica między
CustomEvent
a zwykłym
Event
, który nie ma pola
detail
.

Wysyłanie wydarzeń z dispatchEvent()

Aby "wystrzelić" wydarzenie, używamy metody

dispatchEvent()
na dowolnym elemencie DOM:

1// Wysłanie wydarzenia na konkretnym elemencie
2const monitorPanel = document.getElementById('monitor-panel');
3monitorPanel.dispatchEvent(alertEvent);
4
5// Wysłanie wydarzenia na całym dokumencie (globalny broadcast)
6document.dispatchEvent(alertEvent);

Gdy wydarzenie zostanie wysłane, wszystkie zarejestrowane na nie listenery zostaną wywołane synchronicznie - w kolejności ich rejestracji.

Nasłuchiwanie na własne wydarzenia

Nasłuchiwanie na Custom Events działa identycznie jak na standardowe wydarzenia - za pomocą

addEventListener()
:

1// Nasłuchiwanie na dowolnym elemencie
2document.addEventListener('dinoAlert', function(event) {
3  const { species, zone, threatLevel } = event.detail;
4
5  console.log(`ALERT: ${species} wykryty w strefie ${zone}!`);
6  console.log(`Poziom zagrożenia: ${threatLevel}/10`);
7
8  if (threatLevel >= 8) {
9    activateEmergencyProtocol(zone);
10  }
11});

Praktyczny system alertów parku

Połączmy wszystkie elementy w kompletny system komunikacji między modułami:

1// Moduł 1: Generator alertów
2function createParkAlert(alertType, message, data = {}) {
3  const alertEvent = new CustomEvent('parkAlert', {
4    detail: {
5      type: alertType,
6      message: message,
7      timestamp: new Date(),
8      data: data
9    },
10    bubbles: true
11  });
12
13  document.dispatchEvent(alertEvent);
14}
15
16// Moduł 2: Centralny system nasłuchujący
17document.addEventListener('parkAlert', (e) => {
18  const { type, message, timestamp, data } = e.detail;
19
20  console.log(`${timestamp.toLocaleTimeString()} - Alert ${type}: ${message}`);
21
22  switch(type) {
23    case 'security':
24      showSecurityAlert(message, data);
25      break;
26    case 'maintenance':
27      showMaintenanceNotification(message, data);
28      break;
29    case 'visitor':
30      showVisitorInfo(message, data);
31      break;
32    default:
33      showGeneralAlert(message);
34  }
35});
36
37// Moduł 3: Wykrywanie ucieczek dinozaurów
38function handleDinosaurEscape(dinosaurId) {
39  const dinosaur = getDinosaurById(dinosaurId);
40
41  createParkAlert('security', `ALARM! ${dinosaur.name} uciekł z wybiegu!`, {
42    dinosaurId: dinosaurId,
43    location: dinosaur.enclosure,
44    dangerLevel: dinosaur.dangerLevel
45  });
46
47  activateEmergencyProtocols();
48}

Wzorzec Event Bus (szyna zdarzeń)

Custom Events pozwalają zbudować prosty Event Bus - centralny punkt komunikacji między niezależnymi modułami aplikacji:

1class ParkEventBus {
2  constructor() {
3    this.target = new EventTarget();
4  }
5
6  emit(eventName, data) {
7    this.target.dispatchEvent(
8      new CustomEvent(eventName, { detail: data })
9    );
10  }
11
12  on(eventName, callback) {
13    const handler = (e) => callback(e.detail);
14    this.target.addEventListener(eventName, handler);
15    // Zwracamy funkcję do wyrejestrowania
16    return () => this.target.removeEventListener(eventName, handler);
17  }
18}
19
20const bus = new ParkEventBus();
21
22// Moduł monitoringu rejestruje się na alerty
23const unsubscribe = bus.on('fenceBreak', (data) => {
24  console.log(`Ogrodzenie w strefie ${data.zone} uszkodzone!`);
25});
26
27// Moduł sensorów wysyła alert
28bus.emit('fenceBreak', { zone: 'C3', voltage: 0 });
29
30// Gdy moduł jest niszczony - wyrejestrowanie
31unsubscribe();

Dzięki Event Bus moduły nie muszą znać się nawzajem - komunikują się wyłącznie przez wydarzenia, co zapewnia luźne powiązanie (loose coupling) i łatwiejsze testowanie.

Przejdź do CodeWorlds