Przeczytaj
Pełnoprawny, skryptowy język programowania JavaScript umożliwia przeglądarce internetowej podejmowanie decyzji lub inicjowanie działań w zależności od akcji podjętych przez użytkownika w interfejsie witryny.
Taką akcję użytkownika zarejestrowaną przez przeglądarkę określamy w programowaniu jako zdarzenie (ang. event). Zadaniem programisty webowego jest więc przygotowanie obsługi wybranych zdarzeń, czyli w praktyce stworzenie własnego kodu źródłowego, zazwyczaj w postaci funkcji.
Funkcja to w programowaniu fragment kodu realizujący konkretne zadanie. Idealnie więc zgrywa się to ze zdarzeniami zachodzącymi w interfejsie strony – do zajścia wybranego zdarzenia można przecież wygodnie przypisać wywołanie własnej funkcji. Tak właśnie powstaje obsługa zdarzenia zdefiniowana przez programistę.
Czym dokładnie jest zdarzenie?
W praktyce zdarzenia w przeglądarce nie zawsze stanowią jedynie reakcję na akcję internauty. Owszem, najczęściej obsługiwane przez programistę sytuacje rzeczywiście zainicjowane będą bezpośrednimi działaniami użytkownika - na przykład kliknięciem, wskazaniem za pomocą kursora, wciśnięciem klawisza na klawiaturze itd.
Lecz oprócz tego typu bezpośrednich reakcji istnieją także zdarzenia zachodzące wskutek mechaniki działania samej witryny - przykładem jest tu zdarzenie load
, które zachodzi w momencie wczytania np. obrazka, pliku lub nawet całej podstrony. Jaka jest więc pełna i możliwie dokładna definicja zdarzenia?
(ang. event) to dająca się wyróżnić sytuacja zachodząca w oknie przeglądarki internetowej, zarejestrowana automatycznie przez wbudowany w przeglądarkę mechanizm tzw. nasłuchiwania zdarzeń (ang. event listening).
Gdy się nad tym zastanowić, wspomniane nasłuchiwanie zdarzeń nie jest wcale niczym nowym ani zaskakującym w systemach komputerowych. W końcu na tej samej zasadzie działa np. obsługa ikon pulpitu czy paska zadań w systemie Windows albo ekran główny w telefonie z systemem Android.
Choć brzmi to dość niepokojąco, wiele programowalnych urządzeń komputerowych nieustannie śledzi nasze poczynania. Oczywiście dokonuje tego jedynie na ściśle określonych i transparentnych zasadach związanych z udostępnionymi użytkownikowi elementami interfejsu.
Lecz co do zasady, zadaniem dobrze napisanej aplikacji (w tym również aplikacji webowej) jest jak najszybciej reagować na zaistniałe zdarzenia. To właśnie tak pożądana przez użytkowników interaktywność aplikacji, systemu czy urządzenia. Dlatego również przeglądarka internetowa została stworzona według tej samej idei jak najszybszego obsługiwania zdarzeń.
Rodzaje zdarzeń w przeglądarce
Dokonajmy teraz przeglądu popularnych zdarzeń, czyli takich, których obsługę często definiują programiści JavaScript – dla zwiększenia czytelności listy, zdarzenia podzielono na kilka kategorii:
Zdarzenia związane z kursorem myszy
Nazwa zdarzenia | Zastosowanie, czyli kiedy wystąpienie zdarzenia zostanie zarejestrowane podczas nasłuchiwania |
---|---|
| Klasyczne kliknięcie, które rozumiemy jako naciśnięcie przycisku myszy, a następnie jego zwolnienie, które nastąpiło w czasie, gdy wskaźnik (kursor) myszy wciąż znajdował się na elemencie (obiekcie). |
| Dwukrotne kliknięcie elementu (z ang. double click). |
| Wystąpi w sytuacji, gdy przycisk myszy został wciśnięty, kiedy kursor znajdował się na elemencie. W odróżnieniu od zdarzenia |
| Wystąpi w sytuacji, gdy przycisk myszy został zwolniony, kiedy kursor znajdował się na elemencie. W odróżnieniu od zdarzenia |
| Rejestrowane za każdym razem, gdy kursor myszy poruszy się, znajdując się na elemencie. |
| Zachodzi, kiedy wskaźnik myszy wkroczy z obszaru spoza elementu i znajdzie się na obiekcie. Jednak w odróżnieniu od zdarzenia |
| Zachodzi, kiedy wskaźnik myszy wkroczy z obszaru spoza elementu i znajdzie się na obiekcie lub także na jego elementach potomnych w hierarchii DOMhierarchii DOM. |
| Zostanie zarejestrowane, gdy kursor myszy opuści dany obiekt. |
| Zostanie zarejestrowane, gdy kursor myszy opuści dany obiekt lub także jego elementy potomne w hierarchii DOMhierarchii DOM. |
Zdarzenia związane z klawiaturą
Nazwa zdarzenia | Zastosowanie, czyli kiedy wystąpienie zdarzenia zostanie zarejestrowane podczas nasłuchiwania |
---|---|
| Rejestrowane, kiedy klawisz na klawiaturze zostaje wciśnięty. |
| Rejestrowane, kiedy wciśnięty klawisz klawiatury zostaje zwolniony. |
| Zachodzi pomiędzy zdarzeniami |
Zdarzenia w interfejsie witryny
Nazwa zdarzenia | Zastosowanie, czyli kiedy wystąpienie zdarzenia zostanie zarejestrowane podczas nasłuchiwania |
---|---|
| Wystąpi w momencie, gdy element HTML znajdzie się w centrum uwagi – np. gdy używamy w witrynie klawisza |
| W przeciwieństwie do zdarzenia |
| Zachodzi w momencie zmiany rozmiaru widoku dokumentu w przeglądarce. |
| Rejestrowane, kiedy przeglądarka zakończy wczytywanie podstrony. |
| Zachodzi jednokrotnie w momencie, gdy użytkownik opuszcza interfejs – np. kiedy karta przeglądarki zostaje zamknięta lub gdy naciśnięto przycisk |
| Występuje w sytuacji, gdy dany obiekt jest przenoszony w interfejsie. |
| Występuje w sytuacji, gdy dany obiekt jest upuszczany na określonym celu w interfejsie. |
Zdarzenia związane z formularzami
Nazwa zdarzenia | Zastosowanie, czyli kiedy wystąpienie zdarzenia zostanie zarejestrowane podczas nasłuchiwania |
---|---|
| Wystąpi w momencie podsumowania (wysłania) danych całego formularza. |
| Zachodzi w sytuacji zresetowania stanu formularza, czyli wprowadzonych do jego kontrolek danych wejściowych (tekstu, wyborów, wskazań). |
| Zachodzi w momencie, gdy zmienia się zawartość lub stan kontrolki formularza – np. zmieniono tekst w polu |
| Rejestrowane w sytuacji, gdy użytkownik zaznaczy tekst w polu |
| Zostanie zarejestrowane, gdy w polu |
Jak widać, do naszej dyspozycji oddano wiele różnorodnych zdarzeń, których obsługę możemy zdefiniować w języku JavaScript. Powyższa lista stanowi przegląd jedynie najpopularniejszych zdarzeń – w dokumentacji języka JS odnajdziemy ich jeszcze więcej!
Teraz możemy przejść do stworzenia obsługi sytuacji automatycznie rejestrowanych w interfejsie witryny. Dokonamy tego z użyciem własnych funkcji.
Własne funkcje obsługujące zdarzenia
W języku JavaScript zrealizowanie obsługi zdarzenia polega najczęściej na przypisaniu do automatycznej rejestracji tego zajścia w przeglądarce wywołania własnej funkcji.
Jak już wspomnieliśmy, funkcja to wydzielony fragment kodu spełniający konkretne zadanie. Pasuje to wręcz idealnie do stworzenia różnych reakcji elementów interfejsu w odpowiedzi na poczynania internauty czy zajścia w samej przeglądarce.
Istnieje klika metod zdefiniowania tego przypisania wywołania własnej funkcji do momentu zajścia zdarzenia (ang. trigger, - dosł. naciśnięcie spustu broni). Zacznijmy od metody klasycznej, choć nieoptymalnej.
Przypisanie z użyciem atrybutu HTML
Zrealizujmy przypisanie własnej funkcji do obsługi najpopularniejszego zdarzenia click
. Załóżmy, że naszym celem jest wyświetlenie małego okienka dialogowego (ang. alert), za pomocą którego przywitamy się ze światem. Jednak ma to nastąpić nie przy wczytaniu strony do przeglądarki, lecz w momencie kliknięcia w przycisk z napisem Test
.
Klasyczna metoda połączenia wykonania funkcji z obsługą zajścia zdarzenia, jakim jest kliknięcie przycisku, polega na zdefiniowaniu dla przycisku atrybutu HTML
, który wywołanie funkcji ma ustawione jako swoją wartość.
Przycisk zdefiniowany w HTML:
Zwróćmy uwagę na obecność dodatkowego atrybutu HTML
o nazwie onclick
, którego wartość ustawiono na wywołanie funkcji o nazwie hello()
. Ponieważ jest to wywołanie funkcji, zawiera nawiasy okrągłe.
Samą funkcję oczywiście zdefiniujemy już w skrypcie:
Ta klasyczna metoda jest bardzo prosta w zapisie. Reasumując: połączenie funkcji zapisanej w JavaScript z zajściem zdarzenia następuje dzięki zdefiniowaniu w HTML odpowiedniej wartości dodatkowego atrybutu.
Może nas nieco dziwić nazwa tego dodatkowego atrybutu HTML
- dlaczego jest to onclick
, a nie click
, czyli nazwa samego zdarzenia w JavaScript? To właśnie dla odróżnienia tego zapisu w HTML od kodu źródłowego JS użyto dodatkowego przedrostka on
, który należy odczytać jako: podczas zajścia zdarzenia.
Zasada ta obowiązuje oczywiście także w przypadku innych zdarzeń - przykładowe atrybuty możliwe do wykorzystania to: onmousedown
, onload
, onsubmit
.
Częstym skrótem myślowym stosowanym przez wielu programistów jest używanie w mowie potocznej nazw atrybutów jako nazw zdarzeń. Nie jest to jednak formalnie poprawne, gdyż przedrostek on
zawierają tylko atrybuty HTML
, a nie zdarzenia w JavaScript.
Wadą tworzenia atrybutu HTML
jest brak oddzielenia kodu JavaScript od źródła HTML, czyli zmieszanie warstwy zawartości strony (HTML) z front‑endowąfront‑endową mechaniką działania witryny (JavaScript).
Znacznie lepszym wyjściem jest przypisanie wywołania własnej funkcji do obsługi zdarzenia również za pomocą kodu JavaScript, czyli bez konieczności użycia dodatkowych zapisów HTML. W tym celu trzeba użyć tzw. nasłuchiwacza zdarzeń.
Zdefiniowanie nasłuchiwacza w JavaScript
Naszym celem ponownie jest wyświetlenie małego okienka dialogowego, za pomocą którego przywitamy się ze światem po kliknięciu w przycisk z napisem Test
.
Przycisk w HTML:
Tym razem jednak nie użyjemy atrybutu onclick
, tylko metody addEventListener()
wywołanej na rzecz obiektu, którym jest nasz przycisk. Aby móc uchwycić obiekt, do kontrolki formularza dodaliśmy klasyczny atrybut id="test"
.
Może się to wydawać trochę dziwne - nowy sposób miał przecież zaoszczędzić nam tworzenia dodatkowego atrybutu HTML
, a tymczasem do przycisku dodano atrybut id
.
Owszem, jednak zadaniem atrybutu id
jest stworzenie identyfikatora, który może posłużyć do uchwycenia obiektu, a nie przypisanie własnej funkcji do obsługi zdarzenia.
Ponadto, gdyby zamiast metody getElementById()
użyć do uchwycenia przycisku np. metody querySelector()
, to atrybut id
okazałby się całkowicie zbędny.
Pora zatem na podpięcie wykonania naszej funkcji hello()
w nasłuchiwaczu zdarzeń - tym razem zostanie to już zrealizowane za pomocą kodu JavaScript
, a nie z użyciem atrybutu HTML
:
W tej metodzie lepiej oddzielono źródło JavaScript od języka opisowego HTML – nie mieszamy warstwy zawartości witryny oraz jej mechaniki. Przypisanie funkcji do zdarzenia nastąpiło przy użyciu instrukcji języka JavaScript, a nie dodatkowego atrybutu HTML.
Przeglądarka „nasłuchuje” zajścia zdarzenia i w momencie, gdy kliknięcie rzeczywiście następuje, wywołana zostaje do pracy funkcja o nazwie hello
.
Zwróćmy uwagę, że tym razem odniesienie nastąpiło przez tzw. referencję (odniesienie po nazwie), a więc bez dodatkowych nawiasów okrągłych, jak to miało miejsce w wartości atrybutu onclick
.
Referencja, funkcja anonimowa, funkcja strzałkowa
Oprócz przekazania funkcji do nasłuchiwacza poprzez referencję, można tego dokonać także na dwa inne sposoby – przyjrzyjmy się im bliżej.
Pierwszy sposób już znamy - wskazujemy przypisanie własnej funkcji do nasłuchiwacza poprzez referencję, czyli podając samą nazwę funkcji, bez obecności nawiasów:
Możemy także skorzystać z tzw. funkcji strzałkowej, czyli takiej, która zawiera uproszczoną, krótszą składnię aniżeli klasyczne wyrażenie funkcji:
Oprócz tego możemy także zdecydować się na funkcję anonimową, czyli zdefiniowaną klasycznie z użyciem klauzuli function
, lecz bez podania nazwy funkcji:
Zapisy skrócone wydają się atrakcyjne, co zatem zyskujemy, stosując referencję do własnej funkcji? Otóż wówczas możliwe staje się odpięcie wywołania funkcji od nasłuchiwacza zdarzeń:
Tym razem funkcja hello()
po wyświetleniu okna dialogowego „odpina” swoje przypisanie do nasłuchiwacza zdarzenia kliknięcia przycisku – kolejne kliknięcia nie spowodują już pojawienia się okienka.
Jak zauważyliśmy, wywołanie metody removeEventListener()
wymaga przesłania do niej dwóch argumentów - najpierw jest rodzaj zdarzenia, a później nazwa funkcji przypiętej do jego obsługi. To właśnie dlatego użycie funkcji anonimowych wyklucza użycie metody - nie dysponujemy przecież nazwą funkcji.
Kiedy zatem warto użyć zapisów skróconych? Logiczna odpowiedź nasuwa się sama - przede wszystkim tam, gdzie absolutnie nie zakładamy odpięcia wykonywanych instrukcji od nasłuchiwania zdarzenia.
Ponadto istnieje jeszcze kilka dodatkowych ograniczeń zaawansowanych, na przykład niemożność użycia w funkcjach strzałkowych słów kluczowych this
oraz super
, jak również brak dostępu do specjalnego obiektu dostępnego w funkcjach, który nosi nazwę arguments
.
Warto także pamiętać, że funkcje strzałkowe nie są obsługiwane w przeglądarkach z rodziny Internet Explorer.
Słownik
(ang. Document Object Model) określony przez organizację W3C standardowy model struktury całego dokumentu HTML, wykorzystywany przez współczesne przeglądarki internetowe; model ten jest obiektowy i niezależny od platformy sprzętowej czy używanego w projekcie języka programowania
ogół technologii webowych (HTML, CSS oraz w wielu zastosowaniach JavaScript), w których kody źródłowe wykonywane są przez przeglądarkę internetową klienta witryny oraz pozostają jawne, czyli może do nich zajrzeć każdy użytkownik serwisu, niezależnie od posiadanych uprawnień