JAVASCRIPT Zdarzenia
Rodzaje zdarzeń
Zdarzenia to rzeczy, które wykonują się na elementach HTML. Przykładowo kliknięcie przez użytkownika przycisku wywołuje zdarzenie click, najechanie myszą na obrazek – mouseover, wybranie elementu – focus, wysłanie formularza – submit, naciśnięcie przycisku na klawiaturze – keydown.
Poniżej bardziej przedstawiam tabelę z listą dostępnych rodzajów zdarzeń:
Rodzaj zdarzenia | Opis |
click | element kliknięty |
change | opuszczamy element, który zmienił zawartość |
mouseover | kursor na elemencie |
mouseout | kursor opuścił element |
mouseenter | kursor wjechał na element |
mouseleave | kursor zjechał z elementu |
dblclick | podwójne kliknięcie elementu |
submit | wysłanie formularza |
resize | zmiana wielkości okna |
focus | element został wybrany |
blur | element przestał być aktywny |
keydown | naciśnięto klawisz na klawiaturze |
keyup | puszczono klawisz |
input | wciśnięty jest klawisz |
load | obiekt został załadowany |
contextmenu | wciśnięto prawy przycisk myszy i pojawiło się menu kontekstowe |
wheel | kręcone jest koło myszy |
select | zaznaczono zawartość obiektu |
unload | strona jest opuszczana |
animationstart | rozpoczyna się animacja |
animationend | kończy się animacja |
transitionstart | rozpoczyna się efekt przejścia |
transitionend | koniec efektu przejścia |
transitionrun | trwa efekt przejścia |
Mix HTML i JS
Najprostszą formą wykorzystania zdarzeń języka JavaScript jest dodanie atrybutu zdarzenia wywołującego daną metodę. Na poniższym przykładzie atrybut onclick, który po kliknięciu przez użytkownika odnośnika wywoła funkcję alert ze stosownym komunikatem.
<a href="#" onclick="alert('Okno otwarte. Zamknij to okno!')">Klik!</a>
Mieszamy w ten sposób ze sobą treści skryptowe i znaczniki html. Chcemy tego jednak uniknąć, zastosujemy zatem inne metody wywołania zdarzeń, o których poniżej.
Wywołanie zdarzenia, a załadowanie strony
Zdarzenie wywołujemy na elementach HTML. Warto zatroszczyć się o to, aby te elementy zostały wcześniej wczytane przez przeglądarkę.
Aby o to zadbać możemy umieścić nasz skrypt na końcu kodu strony, przed samym zamknięciem znacznika </body>, możemy również skorzystać ze zdarzenia DOMContentLoaded.
document.addEventListener("DOMContentLoaded", function(event) { console.log("DOM wczytany, można działać..."); });
document.querySelector();
Zwraca pierwszy napotkany w kodzie strony element spełniający kryteria zawarte w nawiasach okrągłych.
Przykładowo może to być poszukiwanie paragrafu:
document.querySelector("p");
Paragraf o nazwie klasy “example”:
document.querySelector("p.example");
Bądź na przykład element o id test:
document.querySelector("#test");
Poniżej pełniejszy przykład zastosowania. Skrypt po kliknięciu przycisku o id #but wypisze stosowny komunikat w konsoli przeglądarki.
function klikme() { console.log('Klik!'); } const element = document.querySelector('#but'); element.onclick = klikme; element.onmouseover = function() { console.log('Najechano przycisk!'); }
Poniżej w pełni działający przykład. Skopiuj go do pliku html, uruchom w przeglądarce i przeanalizuj działanie.
<!DOCTYPE HTML> <html lang="pl"> <head> <meta charset="utf-8"> <title>JS: Zdarzenia</title> <style> </style> <script> document.addEventListener("DOMContentLoaded", function(event) { function klikme() { console.log('Klik!'); } const element = document.querySelector('#but'); element.onclick = klikme; element.onmouseover = function() { console.log('Najechano przycisk!'); } }); </script> </head> <body> <button id='but'>Zoba zoba</button> </body> </html>
Jak widzisz na przycisku przechwytujemy dwa różne zdarzenia. Pierwszym z nich jest kliknięcie, które wywołuje metodę klikme, która wypisuje informację o kliknięciu do konsoli. Dodatkowo przy każdorazowym najechaniu kursorem na przycisk również informacja o tym wypisywana jest w konsoli, a to dzięki zastosowaniu mouseover.
Nie jeden, a wiele…
Zastosowanie document.querySelector działało dla pierwszego napotkanego elementu. Co jednak jeśli chcemy wywołać zdarzenie na większej ilości takich samych elementów? Z pomocą przyjdzie nam:
document.querySelectorAll();
Spowoduje wybranie wszystkich elementów spełniających zadane kryteria (rodzaj elementu, nazwa klasy, itp.).
Przykładowo dodajmy nazwę klasy “done” do każdego paragrafu w dokumencie:
const p = document.querySelectorAll('p'); for (var i=0; i<p.length; i++) { p[i].onclick = function() { this.classList.add('done'); } }
- document.querySelectorAll(‘p’) wybiera nam wszystkie paragrafy
- for (var i=0; i<p.length; i++) pętla for przegląda je wszystkie począwszy od pierwszego (indeks 0), skończywszy na ostatnim: p.length – 1
- p[i].onclick dla paragrafu o indeksie 0 – ilość paragrafów -1 po wychwyceniu zdarzenia onclick wywoła funkcję
- this.classList.add(‘done’) która doda do listy klas paragrafu kolejną o nazwie “done”
Poniżej kompletny przykład do analizy:
<!DOCTYPE HTML> <html lang="pl"> <head> <meta charset="utf-8"> <title>JS: Zdarzenia</title> <style> .done{ background: green; color: white; } </style> <script> document.addEventListener("DOMContentLoaded", function(event) { const p = document.querySelectorAll('p'); for (let i=0; i<p.length; i++) { p[i].onclick = function() { this.classList.add('done'); } } }); </script> </head> <body> <p>jeden</p> <p>dwa</p> <p>trzy</p> </body> </html>
Klasa dodana, klasa usunięta
Wiemy już jak dodać nową nazwę klasy do elementu. Czas móc ją również usunąć. Wykorzystujemy do tego classList.remove(‘nazwa_klasy’);
Poniżej przykład skryptu, który na zmianę, po kolejnych kliknięciach dodaje i usuwa nazwę klasy done dla klikniętego paragrafu.
document.addEventListener("DOMContentLoaded", function(event) { const p = document.querySelectorAll('p'); for (let i=0; i<p.length; i++) { p[i].onclick = function() { if(this.className == 'done'){ this.classList.remove('done'); }else{ this.classList.add('done'); } } } });
addEventListener()
Kolejnym sposobem rejestracji zdarzeń jest wykorzystanie addEventListener(). Metoda ta przyjmuje trzy argumenty: typ zdarzenia, funkcja do wywołania oraz trzeci, opcjonalny argument – wskazujący jak dane zdarzenia mają się zachować.
Przykładowo dla naszego elementu o klasie “par” po przechwyceniu zdarzenia kliknięcia wykonamy funkcję klikme() oraz drugą funkcję, zmieniającą kolor tekstu.
const element = document.querySelector('.par'); element.addEventListener('click', klikme); element.addEventListener('click', function() { this.style.color = 'red'; });
Przykład do analizy:
<!DOCTYPE HTML> <html lang="pl"> <head> <meta charset="utf-8"> <title>JS: Zdarzenia</title> <style> .done{ background: green; color: white; } </style> <script> function klikme() { console.log('Klik!'); } document.addEventListener("DOMContentLoaded", function(event) { const element = document.querySelector('.par'); // 2 zdarzenia dla jednego kliknięcia element.addEventListener('click', klikme); element.addEventListener('click', function() { this.style.color = 'red'; }); }); </script> </head> <body> <p class='par'>jeden</p> </body> </html>
Przechwycenie klawisza
Właściwość key zdarzenia przechowuje nam wartość naciśniętego klawisza. Dzięki wykorzystaniu poniższych właściwości możemy wyciągnąć wartość naciśniętego przycisku, jego kod ASCII oraz sprawdzić, czy naciśnięty został któryś z trójki przycisków: alt, ctrl, shift.
Właściwość | Opis |
e.key | naciśnięty klawisz |
e.altKey | czy klawisz alt został naciśnięty |
e.ctrlKey | czy klawisz ctrl został naciśnięty |
e.shiftKey | czy klawisz shift został naciśnięty |
e.keyCode | kod ascii naciśniętego klawisza |
Poniżej przykład zastosowania powyższej wiedzy. Skopiuj poniższy kod do pliku html, przetestuj go w przeglądarce i przeanalizuj.
<!DOCTYPE HTML> <html lang="pl"> <head> <meta charset="utf-8"> <title>JS: Events</title> <style> .done{ background: green; color: white; } </style> <script> document.addEventListener("DOMContentLoaded", function() { const textF = document.querySelector('#inputin'); textF.addEventListener('keyup', function(e) { //console.log('Naciśnięto przycisk: ' + e.key); document.querySelector('#printit').innerText += e.key; }); }); </script> </head> <body> <input type='text' id='inputin'/> <p id='printit'></p> </body> </html>