"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."
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.
"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 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."
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}"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ł."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}"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."
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}"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."
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}"Oprócz właściwości," Ray pokazuje następny ekran, "obiekt Event ma też metody - narzędzia do kontrolowania zachowania wydarzenia."
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}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 21const 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"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();"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ł wydarzenieevent.currentTarget - element z listeneremevent.type - typ wydarzeniaevent.clientX/Y, event.pageX/Y - pozycje kursoraevent.ctrlKey, event.shiftKey, event.altKey - klawisze modyfikująceevent.button - przycisk myszyKluczowe metody:
event.preventDefault() - blokuj domyślną akcjęevent.stopPropagation() - zatrzymaj propagacjęevent.stopImmediatePropagation() - zatrzymaj wszystkie listenery