← Lekcje
JavaScript · lekcja 27

Zdarzenia 2/5:
nie tylko klik - inne zdarzenia

Plan tematu (5 godzin):

  1. Godzina 1: zdarzenie, addEventListener, obiekt zdarzenia
  2. Godzina 2 (dziś): nie tylko klik - inne zdarzenia (keydown, submit)
  3. Godzina 3: budujemy planszę 3×3 (kółko i krzyżyk)
  4. Godzina 4: kliknięcie pola zapisuje ruch
  5. Godzina 5: kto wygrał - sprawdzamy planszę
Rozgrzewka · 3 minuty

Rozgrzewka: zdarzenia z poprzedniej lekcji

  1. Dlaczego addEventListener jest zalecany zamiast atrybutu onclick w HTML?
  2. Jakie dwa argumenty przyjmuje metoda addEventListener?
  3. Co wskazuje event.target wewnątrz funkcji obsługi zdarzenia?
Część 1 · Inne zdarzenia niż click

Nie tylko click: inne rodzaje zdarzeń

Na poprzedniej lekcji nasłuchiwaliście zdarzenia click - kliknięcia myszką. Przeglądarka wystrzeliwuje też inne zdarzenia: naciśnięcie klawisza, wysłanie formularza, koniec wczytywania strony. Każde nasłuchujecie tą samą metodą addEventListener, tylko z inną nazwą zdarzenia jako pierwszym argumentem.

ZDARZENIE KIEDY SIĘ ZDARZA PRZYKŁAD click keydown submit load kliknięcie elementu myszką naciśnięcie klawisza na klawiaturze wysłanie formularza (przycisk albo Enter) strona kończy się wczytywać przycisk „Wyślij” pole tekstowe z licznikiem formularz signup cały dokument
MDN: Learn_web_development/Core/Scripting/Events, sekcja „What is an event?” („The user presses a key on the keyboard. […] A form is submitted. […] A web page finishes loading.”, tłum. własne: „Użytkownik naciska klawisz na klawiaturze. […] Formularz zostaje wysłany. […] Strona kończy się wczytywać.”); keydown: sekcja „Event objects” („the keydown event fires when the user presses a key”, tłum. własne: „zdarzenie keydown wystrzeliwuje, gdy użytkownik naciska klawisz”); submit: sekcja „Getting hands-on with events” („the submit event is fired on a form when it is submitted”, tłum. własne: „zdarzenie submit wystrzeliwuje na formularzu, gdy zostaje on wysłany”)
Część 2 · Formularz i zdarzenie submit

submit: zdarzenie wysłania formularza

Gdy wypełnicie formularz i klikniecie przycisk „Wyślij” (albo wciśniecie Enter w polu), przeglądarka domyślnie wysyła dane na serwer i przeładowuje stronę. Zdarzenie submit wystrzeliwuje dokładnie w tym momencie - zanim to się stanie, więc możecie jeszcze zareagować.

FORMULARZ #signup #nameField Wyślij odpala zdarzenie "submit" DOMYŚLNE DZIAŁANIE wysłanie danych na serwer i przeładowanie strony (chcemy to czasem zatrzymać)
const form = document.getElementById("signup");

form.addEventListener("submit", handleSubmit);
MDN: Learn_web_development/Core/Scripting/Events, sekcja „Getting hands-on with events” („When you fill in the details and click the submit button, the natural behavior is for the data to be submitted to a specified page on the server for processing, and the browser to be redirected”, tłum. własne: „Gdy wypełnicie dane i klikniecie przycisk wysyłania, naturalnym zachowaniem jest wysłanie danych na wskazaną stronę na serwerze do przetworzenia, a przeglądarka zostaje przekierowana”)
Część 3 · Zatrzymujemy domyślne działanie

event.preventDefault(): zatrzymaj domyślne działanie przeglądarki

Obiekt zdarzenia event (poprzednia lekcja) ma metodę preventDefault(). Wywołana wewnątrz funkcji obsługi zatrzymuje to, co przeglądarka zrobiłaby domyślnie - tu: wysłanie formularza i przeładowanie strony. Reszta funkcji (np. komunikat o błędzie) wykonuje się dalej.

function handleSubmit(event) {
  if (nameField.value === "") {
    event.preventDefault();
    // formularz nie zostanie wysłany
  }
}
MDN, Web/API/Event/preventDefault: „The preventDefault() method of the Event interface tells the user agent that the event is being explicitly handled, so its default action […] should not be taken.” - „Metoda preventDefault() interfejsu Event mówi programowi klienckiemu (przeglądarce), że zdarzenie jest jawnie obsługiwane, więc jego domyślne działanie […] nie powinno zostać podjęte.” (tłum. własne)
Część 4 · Zdarzenie keydown i licznik

keydown: liczymy naciśnięcia klawiszy

Zdarzenie keydown wystrzeliwuje za każdym razem, gdy naciśniecie klawisz w polu, które ma fokus (jest aktywne). Licznik keyCount rośnie o 1 przy każdym naciśnięciu.

#nameField pole tekstowe keydown keydown keydown keyCount=1 keyCount=2 keyCount=3

Ciekawostka z MDN: obok keydown istniało kiedyś zdarzenie keypress, uruchamiane tylko przy klawiszach, które wpisują znak - literach, cyfrach, Enterze. Strzałki i Escape go nie odpalały. MDN oznacza dziś keypress jako przestarzałe i każe używać w zamian keydown albo beforeinput.

let keyCount = 0;

function handleKeydown() {
  keyCount = keyCount + 1;
  console.log(keyCount);
}

nameField.addEventListener("keydown", handleKeydown);
MDN: Learn_web_development/Core/Scripting/Events, sekcja „Event objects” („the keydown event fires when the user presses a key. Its event object is a KeyboardEvent, which is a specialized Event object with a key property that tells you which key was pressed”, tłum. własne: „zdarzenie keydown wystrzeliwuje, gdy użytkownik naciska klawisz. Jego obiekt zdarzenia to KeyboardEvent, wyspecjalizowany obiekt Event z właściwością key, która mówi, jaki klawisz został naciśnięty”)
Część 5 · Cały przykład razem

Kod: formularz, submit i keydown

page.html:

<form id="signup">
  <input type="text" id="nameField" placeholder="Twoje imię">
  <button type="submit">Wyślij</button>
</form>

script.js:

const form = document.getElementById("signup");
const nameField = document.getElementById("nameField");
let keyCount = 0;

function handleSubmit(event) {
  if (nameField.value === "") {
    event.preventDefault();
  }
}

function handleKeydown() {
  keyCount = keyCount + 1;
}

form.addEventListener("submit", handleSubmit);
nameField.addEventListener("keydown", handleKeydown);
Kod zgodny ze składnią submit/preventDefault (slajdy 4-5) i keydown (slajd 6)
Egzamin E.14 i EE.09

Tak pytają na egzaminie

1.

Które zdarzenie pozwala wykonać kod w języku JavaScript w chwili wysyłania formularza HTML i zablokować lub pozwolić na jego wysłanie?

  1. onClick
  2. onEnter
  3. onSubmit
  4. onChange

2.

W JavaScript wywołanie zdarzenia onKeydown nastąpi wtedy, gdy klawisz

  1. myszki został naciśnięty.
  2. myszki został zwolniony.
  3. klawiatury został naciśnięty.
  4. klawiatury został zwolniony.
CKE, EE.09, styczeń 2021, zadanie 34 · CKE, E.14, styczeń 2019, zadanie 38
Ćwiczenie przy komputerze · 18 minut

Ćwiczenie: formularz, który nie wyśle pustego pola

  1. Otwórz page.html z poprzednich lekcji. Dodaj formularz: <form id="signup"><input type="text" id="nameField"><button type="submit">Wyślij</button></form>.
  2. W script.js pobierz formularz i pole: const form = document.getElementById("signup"); i const nameField = document.getElementById("nameField");
  3. Napisz funkcję handleSubmit(event) - jeśli nameField.value === "", wywołaj event.preventDefault().
  4. Podepnij nasłuch: form.addEventListener("submit", handleSubmit);
  5. Sprawdź w przeglądarce: kliknij Wyślij z pustym polem (strona nie powinna się przeładować), potem wpisz imię i kliknij Wyślij ponownie (przeładowanie następuje).
  6. Dla chętnych: zapisz zmiany w swoim repozytorium - commit „Dodaje walidację formularza przy submit”.
Na koniec

Sprawdź się

  1. Jakie dwa zdarzenia inne niż click poznaliście dziś i kiedy każde z nich się zdarza?
  2. Co robi event.preventDefault() wywołane w funkcji obsługi zdarzenia submit?
  3. Co się stanie, jeśli w formularzu z ćwiczenia NIE wywołacie preventDefault(), gdy pole jest puste?

To tyle na dziś - kolejny temat: budujemy planszę 3×3.

Poza szkołą

A jak to wygląda w produkcji?

Na lekcjiW produkcjiStatus
Puste pole blokowane tylko w JavaScriptAtrybut HTML required blokuje wysłanie bez JS, a serwer i tak sprawdza dane jeszcze raz - JavaScript w przeglądarce da się wyłączyćrozszerzane
Ręczny if sprawdzający jedno poleBiblioteki formularzy (np. React Hook Form) same zbierają błędy wielu pól i pokazują komunikatyzastępowane
keydown do liczenia naciśnięćDo śledzenia bieżącej wartości pola częściej używa się zdarzenia input - reaguje też na wklejenie i autouzupełnianie, nie tylko na klawiszzastępowane (dla wartości pola)
Zdarzenie load na całym dokumencieKod, który nie potrzebuje obrazów, częściej czeka na DOMContentLoaded - odpala się szybciej, bo nie czeka na wczytanie grafikzastępowane (dla samego HTML)
MDN: Learn_web_development/Core/Scripting/Events (zdarzenia submit/keydown/load, slajdy 3-6)