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

Obiekt Event i jego właściwości

"Każdy raport z sensorów w parku," Ray Arnold otwiera szczegółową dokumentację systemu, "zawiera precyzyjne informacje: gdzie, kiedy, jakiego typu wydarzenie, z jaką intensywnością. Podobnie obiekt Event w JavaScript to kompletny raport o tym, co się wydarzyło w przeglądarce."

Ray wskazuje na monitor pokazujący dane z czujnika ruchu przy zagrodzie T-Rexa. "Widzisz? Czas: 14:23:47, lokalizacja: sektor B-7, typ ruchu: szybki, kierunek: północny. Każda informacja jest kluczowa dla właściwej reakcji."

Czym jest obiekt Event?

Każde wydarzenie w JavaScript automatycznie tworzy obiekt Event, który jest przekazywany do funkcji obsługującej jako pierwszy parametr. Ten obiekt zawiera wszystkie istotne informacje o wydarzeniu - od pozycji kursora, przez wciśnięte klawisze, aż po element, który wywołał wydarzenie.

Podstawowa anatomia obiektu Event

"Zacznijmy od fundamentów," mówi Ray, otwierając panel diagnostyczny.

1const parkMap = document.getElementById('interactive-map');
2
3parkMap.addEventListener('click', function(event) {
4  // event to obiekt zawierający wszystkie informacje
5
6  console.log('=== RAPORT WYDARZENIA ===');
7  console.log('Typ wydarzenia:', event.type); // 'click'
8  console.log('Timestamp:', event.timeStamp); // czas w ms od załadowania strony
9  console.log('Event phase:', event.eventPhase); // 1=capture, 2=target, 3=bubble
10
11  // Informacje o pozycji kliknięcia
12  console.log(`Kliknięto na pozycji: X=${event.clientX}, Y=${event.clientY}`);
13
14  // Element, który został kliknięty
15  console.log('Kliknięty element:', event.target);
16  console.log('Tag name:', event.target.tagName);
17  console.log('ID elementu:', event.target.id);
18
19  // Element, do którego przypisany jest event listener
20  console.log('Element z listenerem:', event.currentTarget);
21
22  // Czy można anulować domyślną akcję?
23  console.log('Cancelable:', event.cancelable);
24
25  // Czy wydarzenie bąbelkuje?
26  console.log('Bubbles:', event.bubbles);
27});

Właściwości pozycji - system współrzędnych

"W Parku Jurajskim," wyjaśnia Ray, "używamy różnych systemów współrzędnych - GPS, lokalne koordynaty sektorów, pozycje względem bram. Podobnie JavaScript oferuje kilka systemów współrzędnych dla pozycji myszy."

Różne typy współrzędnych

1const viewingPlatform = document.getElementById('platform');
2
3viewingPlatform.addEventListener('click', function(event) {
4  console.log('=== SYSTEMY WSPÓŁRZĘDNYCH ===');
5
6  // 1. clientX/Y - pozycja względem okna przeglądarki (viewport)
7  console.log('Viewport:', event.clientX, event.clientY);
8  console.log('To jak pozycja względem Twojego monitora kontrolnego');
9
10  // 2. pageX/Y - pozycja względem całej strony (uwzględnia scroll)
11  console.log('Strona:', event.pageX, event.pageY);
12  console.log('To jak współrzędne na pełnej mapie parku');
13
14  // 3. screenX/Y - pozycja względem całego ekranu
15  console.log('Ekran:', event.screenX, event.screenY);
16  console.log('To jak pozycja GPS - bezwzględna lokalizacja');
17
18  // 4. offsetX/Y - pozycja względem klikniętego elementu
19  console.log('Offset:', event.offsetX, event.offsetY);
20  console.log('To jak pozycja w obrębie konkretnej zagrody');
21
22  // Praktyczne użycie - zaznaczanie obszaru na mapie
23  markLocationOnMap(event.pageX, event.pageY);
24  showCoordinatesInfo(event.clientX, event.clientY);
25});
26
27function markLocationOnMap(x, y) {
28  const marker = document.createElement('div');
29  marker.className = 'location-marker';
30  marker.style.left = x + 'px';
31  marker.style.top = y + 'px';
32  document.body.appendChild(marker);
33
34  console.log(`Zaznaczono lokalizację na mapie: (${x}, ${y})`);
35}
36
37function showCoordinatesInfo(clientX, clientY) {
38  const tooltip = document.getElementById('coordinates-tooltip');
39  tooltip.textContent = `Pozycja: X=${clientX}, Y=${clientY}`;
40  tooltip.style.left = (clientX + 10) + 'px';
41  tooltip.style.top = (clientY + 10) + 'px';
42  tooltip.style.display = 'block';
43}

target vs currentTarget - kluczowa różnica

"To jeden z najczęstszych błędów," ostrzega Ray. "Mylenie

target
z
currentTarget
. To jak mylenie dinozaura, który uciekł, z zagrodą, z której uciekł."

Zrozumienie różnicy

1// HTML:
2// <div id="enclosure" class="dino-enclosure">
3//   <div class="info-panel">
4//     <h3>Zagroda T-Rex</h3>
5//     <button class="feed-button">Nakarm</button>
6//     <button class="status-button">Status</button>
7//   </div>
8// </div>
9
10const enclosure = document.getElementById('enclosure');
11
12enclosure.addEventListener('click', function(event) {
13  // target - element, który RZECZYWIŚCIE został kliknięty
14  console.log('Target (kliknięty element):', event.target);
15  console.log('Target tag:', event.target.tagName);
16
17  // currentTarget - element, do którego przypisany jest listener
18  console.log('CurrentTarget (element z listenerem):', event.currentTarget);
19  console.log('CurrentTarget ID:', event.currentTarget.id); // zawsze 'enclosure'
20
21  // Praktyczny przykład
22  if (event.target.classList.contains('feed-button')) {
23    console.log('Kliknięto przycisk karmienia');
24    console.log('W zagrodzie:', event.currentTarget.id);
25    feedDinosaur(event.currentTarget.id);
26  } else if (event.target.classList.contains('status-button')) {
27    console.log('Kliknięto przycisk statusu');
28    console.log('Dla zagrody:', event.currentTarget.id);
29    showEnclosureStatus(event.currentTarget.id);
30  } else {
31    console.log('Kliknięto gdzieś w zagrodzie, ale nie w przycisk');
32  }
33});
34
35function feedDinosaur(enclosureId) {
36  console.log(`Rozpoczynam karmienie w zagrodzie: ${enclosureId}`);
37  console.log('Aktywuję system bezpieczeństwa...');
38  console.log('Podaję pokarm...');
39  console.log('Karmienie zakończone');
40}
41
42function showEnclosureStatus(enclosureId) {
43  console.log(`=== STATUS ZAGRODY ${enclosureId} ===`);
44  console.log('Temperatura: 28°C');
45  console.log('Wilgotność: 65%');
46  console.log('Ostatnie karmienie: 12:30');
47  console.log('Aktywność dinozaura: Normalna');
48}

Klawisze modyfikujące - wielofunkcyjne akcje

"W systemach krytycznych," wyjaśnia Ray, "często potrzebujemy kombinacji klawiszy dla bezpieczeństwa. Jak dwa klucze do arsenału. Event object pokazuje nam, które klawisze są wciśnięte."

Wykrywanie klawiszy modyfikujących

1const dinosaurCard = document.querySelectorAll('.dinosaur-card');
2
3dinosaurCard.forEach(card => {
4  card.addEventListener('click', function(event) {
5    console.log('=== ANALIZA KLAWISZY ===');
6    console.log('Ctrl wciśnięty:', event.ctrlKey);
7    console.log('Shift wciśnięty:', event.shiftKey);
8    console.log('Alt wciśnięty:', event.altKey);
9    console.log('Meta (Cmd/Win) wciśnięty:', event.metaKey);
10
11    const dinoId = this.dataset.dinoId;
12    const dinoName = this.dataset.dinoName;
13
14    // Różne akcje w zależności od kombinacji klawiszy
15    if (event.ctrlKey && event.shiftKey) {
16      // Ctrl + Shift + Click = Zaawansowane opcje
17      console.log('Otwieranie zaawansowanych opcji dla:', dinoName);
18      openAdvancedOptions(dinoId);
19
20    } else if (event.ctrlKey) {
21      // Ctrl + Click = Dodaj do wielokrotnego wyboru
22      console.log('Dodawanie do selekcji:', dinoName);
23      addToSelection(dinoId);
24      this.classList.toggle('selected');
25
26    } else if (event.shiftKey) {
27      // Shift + Click = Wybierz zakres
28      console.log('Wybór zakresu do:', dinoName);
29      selectRange(dinoId);
30
31    } else if (event.altKey) {
32      // Alt + Click = Szybki podgląd
33      console.log('Szybki podgląd:', dinoName);
34      showQuickPreview(dinoId);
35
36    } else {
37      // Zwykłe kliknięcie
38      console.log('Wybrano:', dinoName);
39      clearSelection();
40      selectSingle(dinoId);
41      this.classList.add('selected');
42    }
43  });
44});
45
46// Implementacja pomocniczych funkcji
47let selectedDinosaurs = [];
48
49function addToSelection(dinoId) {
50  if (!selectedDinosaurs.includes(dinoId)) {
51    selectedDinosaurs.push(dinoId);
52  } else {
53    selectedDinosaurs = selectedDinosaurs.filter(id => id !== dinoId);
54  }
55  console.log('Wybrane dinozaury:', selectedDinosaurs);
56}
57
58function clearSelection() {
59  selectedDinosaurs = [];
60  document.querySelectorAll('.dinosaur-card.selected').forEach(card => {
61    card.classList.remove('selected');
62  });
63  console.log('Wyczyszczono selekcję');
64}
65
66function selectSingle(dinoId) {
67  selectedDinosaurs = [dinoId];
68  console.log('Pojedynczy wybór:', dinoId);
69}
70
71function selectRange(endId) {
72  console.log('Implementacja wyboru zakresu do:', endId);
73  // Logika wyboru zakresu między ostatnim wybranym a aktualnym
74}

Informacje o przycisku myszy

"Różne sensory reagują na różne typy sygnałów," Ray pokazuje panel z trzema przyciskami. "Podobnie możemy reagować różnie na lewy, prawy i środkowy przycisk myszy."

Wykrywanie przycisku myszy

1const interactiveMap = document.getElementById('park-map');
2
3interactiveMap.addEventListener('mousedown', function(event) {
4  console.log('=== INFORMACJE O PRZYCISKU MYSZY ===');
5  console.log('Przycisk:', event.button);
6  console.log('0 = lewy, 1 = środkowy, 2 = prawy');
7  console.log('Buttons (bitmask):', event.buttons);
8
9  const clickX = event.clientX;
10  const clickY = event.clientY;
11
12  switch(event.button) {
13    case 0:
14      // Lewy przycisk - standardowa akcja
15      console.log('Lewy przycisk: Zaznaczanie lokalizacji');
16      selectLocation(clickX, clickY);
17      break;
18
19    case 1:
20      // Środkowy przycisk - nowa karta/okno
21      console.log('Środkowy przycisk: Otwieranie w nowym oknie');
22      event.preventDefault();
23      openInNewWindow(clickX, clickY);
24      break;
25
26    case 2:
27      // Prawy przycisk - menu kontekstowe
28      console.log('Prawy przycisk: Menu kontekstowe');
29      showContextMenu(clickX, clickY);
30      break;
31
32    default:
33      console.log('Nieznany przycisk:', event.button);
34  }
35});
36
37// Blokowanie domyślnego menu kontekstowego
38interactiveMap.addEventListener('contextmenu', function(event) {
39  event.preventDefault();
40  console.log('Zablokowano domyślne menu - używamy własnego');
41});
42
43function selectLocation(x, y) {
44  console.log(`Wybrano lokalizację: (${x}, ${y})`);
45  highlightArea(x, y);
46}
47
48function showContextMenu(x, y) {
49  const menu = document.getElementById('custom-context-menu');
50  menu.style.left = x + 'px';
51  menu.style.top = y + 'px';
52  menu.style.display = 'block';
53
54  console.log('Wyświetlono menu kontekstowe na pozycji:', x, y);
55}

Metody obiektu Event

"Oprócz właściwości," Ray pokazuje następny ekran, "obiekt Event ma też metody - narzędzia do kontrolowania zachowania wydarzenia."

preventDefault() - blokowanie domyślnej akcji

1// Przykład 1: Własna walidacja formularza
2const securityForm = document.getElementById('security-access-form');
3
4securityForm.addEventListener('submit', function(event) {
5  event.preventDefault(); // BLOKUJ domyślne wysłanie formularza
6
7  console.log('Przechwycono wysłanie formularza');
8
9  const formData = new FormData(securityForm);
10  const accessCode = formData.get('access-code');
11  const securityLevel = formData.get('security-level');
12
13  // Własna walidacja
14  if (validateAccessCode(accessCode)) {
15    console.log('Kod dostępu poprawny');
16    grantAccess(securityLevel);
17  } else {
18    console.error('Nieprawidłowy kod dostępu!');
19    showError('Kod dostępu jest nieprawidłowy');
20  }
21});
22
23// Przykład 2: Niestandardowa nawigacja
24const navigationLinks = document.querySelectorAll('a.custom-navigation');
25
26navigationLinks.forEach(link => {
27  link.addEventListener('click', function(event) {
28    event.preventDefault(); // BLOKUJ standardowe przejście
29
30    const targetUrl = this.getAttribute('href');
31    console.log('Przechwycono kliknięcie linku:', targetUrl);
32
33    // Własna logika nawigacji (np. SPA routing)
34    navigateToPage(targetUrl);
35  });
36});
37
38function validateAccessCode(code) {
39  const validCodes = ['ALPHA-7', 'BETA-4', 'GAMMA-9'];
40  return validCodes.includes(code);
41}
42
43function navigateToPage(url) {
44  console.log('Nawigacja do:', url);
45  // Implementacja SPA routing
46  history.pushState({}, '', url);
47  loadPageContent(url);
48}

stopPropagation() - zatrzymywanie propagacji

1// HTML:
2// <div class="park-section" id="section-a">
3//   <div class="enclosure" id="enclosure-1">
4//     <button class="action-button">Akcja</button>
5//   </div>
6// </div>
7
8const parkSection = document.getElementById('section-a');
9const enclosure = document.getElementById('enclosure-1');
10const actionButton = document.querySelector('.action-button');
11
12// Listener na sekcji parku
13parkSection.addEventListener('click', function(event) {
14  console.log('3. Kliknięto sekcję parku');
15  updateSectionStatus();
16});
17
18// Listener na zagrodzie
19enclosure.addEventListener('click', function(event) {
20  console.log('2. Kliknięto zagrodę');
21  event.stopPropagation(); // STOP! Nie propaguj wyżej
22  highlightEnclosure();
23});
24
25// Listener na przycisku
26actionButton.addEventListener('click', function(event) {
27  console.log('1. Kliknięto przycisk akcji');
28  performAction();
29  // Wydarzenie będzie propagować do enclosure, ale tam zostanie zatrzymane
30});
31
32// Bez stopPropagation() w enclosure - zobaczylibyśmy wszystkie 3 logi
33// Z stopPropagation() - zobaczymy tylko 1 i 2

stopImmediatePropagation() - całkowite zatrzymanie

1const emergencyButton = document.getElementById('emergency');
2
3// Pierwszy listener
4emergencyButton.addEventListener('click', function(event) {
5  console.log('1. Pierwszy listener - aktywacja alarmu');
6  activateAlarm();
7
8  event.stopImmediatePropagation(); // STOP WSZYSTKO!
9});
10
11// Drugi listener - NIE wykona się!
12emergencyButton.addEventListener('click', function(event) {
13  console.log('2. Ten listener się NIE wykona');
14  closeGates();
15});
16
17// Trzeci listener - NIE wykona się!
18emergencyButton.addEventListener('click', function(event) {
19  console.log('3. Ten też się NIE wykona');
20  notifyStaff();
21});
22
23// Po kliknięciu zobaczymy tylko pierwszy log

Praktyczny system monitoringu

"Połączmy wszystko w działający system," mówi Ray, otwierając główny kod.

1class DinosaurMonitoringSystem {
2  constructor() {
3    this.selectedDinosaurs = [];
4    this.monitoringActive = false;
5    this.initialize();
6  }
7
8  initialize() {
9    console.log('Inicjalizacja systemu monitoringu dinozaurów');
10    this.setupEventListeners();
11  }
12
13  setupEventListeners() {
14    const dinosaurCards = document.querySelectorAll('.dinosaur-card');
15
16    dinosaurCards.forEach(card => {
17      // Click event z pełną analizą
18      card.addEventListener('click', (event) => {
19        this.handleDinosaurClick(event);
20      });
21
22      // Context menu
23      card.addEventListener('contextmenu', (event) => {
24        event.preventDefault();
25        this.showDinosaurMenu(event);
26      });
27
28      // Hover effects
29      card.addEventListener('mouseenter', (event) => {
30        this.showQuickInfo(event);
31      });
32
33      card.addEventListener('mouseleave', (event) => {
34        this.hideQuickInfo(event);
35      });
36    });
37  }
38
39  handleDinosaurClick(event) {
40    const card = event.currentTarget;
41    const dinoId = card.dataset.dinoId;
42    const dinoName = card.dataset.dinoName;
43
44    console.log('=== RAPORT KLIKNIĘCIA ===');
45    console.log('Dinozaur:', dinoName);
46    console.log('Pozycja kliknięcia:', event.clientX, event.clientY);
47    console.log('Timestamp:', event.timeStamp);
48    console.log('Ctrl:', event.ctrlKey);
49    console.log('Shift:', event.shiftKey);
50    console.log('Alt:', event.altKey);
51    console.log('Przycisk myszy:', event.button);
52
53    // Logika selekcji
54    if (event.ctrlKey) {
55      this.toggleSelection(dinoId, card);
56    } else if (event.shiftKey) {
57      this.selectRange(dinoId);
58    } else {
59      this.selectSingle(dinoId, card);
60    }
61  }
62
63  toggleSelection(dinoId, card) {
64    const index = this.selectedDinosaurs.indexOf(dinoId);
65
66    if (index === -1) {
67      this.selectedDinosaurs.push(dinoId);
68      card.classList.add('selected');
69      console.log(`Dodano ${dinoId} do selekcji`);
70    } else {
71      this.selectedDinosaurs.splice(index, 1);
72      card.classList.remove('selected');
73      console.log(`Usunięto ${dinoId} z selekcji`);
74    }
75
76    console.log('Wybrane dinozaury:', this.selectedDinosaurs);
77  }
78
79  selectSingle(dinoId, card) {
80    // Wyczyść poprzednią selekcję
81    document.querySelectorAll('.dinosaur-card.selected').forEach(c => {
82      c.classList.remove('selected');
83    });
84
85    this.selectedDinosaurs = [dinoId];
86    card.classList.add('selected');
87
88    console.log('Wybrano pojedynczego dinozaura:', dinoId);
89  }
90
91  showDinosaurMenu(event) {
92    const card = event.currentTarget;
93    const dinoId = card.dataset.dinoId;
94
95    console.log('Wyświetlanie menu kontekstowego dla:', dinoId);
96    console.log('Pozycja:', event.clientX, event.clientY);
97
98    // Tutaj byłaby logika wyświetlania menu
99  }
100
101  showQuickInfo(event) {
102    const card = event.currentTarget;
103    const dinoName = card.dataset.dinoName;
104
105    console.log(`Najechano na: ${dinoName}`);
106    console.log('Pozycja myszy:', event.clientX, event.clientY);
107  }
108
109  hideQuickInfo(event) {
110    console.log('Opuszczono kartę dinozaura');
111  }
112}
113
114// Inicjalizacja systemu
115const monitoringSystem = new DinosaurMonitoringSystem();

Podsumowanie

"Obiekt Event," podsumowuje Ray, "to Twoje okno do świata interakcji użytkownika. Każda właściwość, każda metoda ma swoje znaczenie i zastosowanie. Podobnie jak każdy odczyt z sensora w Parku Jurajskim pomaga nam utrzymać bezpieczeństwo, tak właściwości Event pomagają Ci tworzyć precyzyjne, responsywne aplikacje."

Kluczowe właściwości:

  • event.target
    - element, który wywołał wydarzenie
  • event.currentTarget
    - element z listenerem
  • event.type
    - typ wydarzenia
  • event.clientX/Y
    ,
    event.pageX/Y
    - pozycje kursora
  • event.ctrlKey
    ,
    event.shiftKey
    ,
    event.altKey
    - klawisze modyfikujące
  • event.button
    - przycisk myszy

Kluczowe metody:

  • event.preventDefault()
    - blokuj domyślną akcję
  • event.stopPropagation()
    - zatrzymaj propagację
  • event.stopImmediatePropagation()
    - zatrzymaj wszystkie listenery
Przejdź do CodeWorlds