Lekce 17 - Zpracování událostí DOM pomocí posluchačů v JavaScriptu
V minulé lekci, Základy práce s DOM a události v JavaScriptu, jsme začali tou nejčastěji používanou
metodou DOMu - getElementById()
a řekli jsme si něco o
událostech.
V dnešním tutoriálu základů JavaScriptu budeme pokračovat v práci s elementy DOM a jejich událostmi. Představíme si posluchače událostí a dozvíme se, proč je lepší používat právě posluchače pro zpracování událostí. Naši jednoduchou kalkulačku pak ještě vylepšíme pomocí anonymní funkce a ukážeme si, jak aplikaci správně rozdělit do více souborů. Docílíme tím oddělení HTML a JavaScript kódu a zpřehledníme tak celkovou strukturu naší aplikace.
Posluchač událostí
Ačkoli události typu onclick
jsou stále funkční a mohou
být vhodné pro jednoduché účely, ukážeme si ještě druhý způsob
zpracování událostí. Tlačítku v něm pomocí metody
addEventListener()
přidáme posluchače
událostí. Tato metoda umožňuje přiřadit více
obslužných funkcí ke stejné události na jednom elementu. Stejně
tak můžeme jednomu elementu přiřadit posluchače různých
událostí (například kliknutí, najetí myší, stisk klávesy) a
každou z těchto událostí obsloužit nějakou funkcí.
V prvním parametru metody addEventListener()
uvádíme
název události a ve druhém funkci, která se má
provést.
Nejprve si připomeňme náš původní JavaScript kód:
let tlacitkoElement = document.getElementById("tlacitko"); let cislo1Element = document.getElementById("cislo1"); let cislo2Element = document.getElementById("cislo2"); function secti() { let cislo1 = parseFloat(cislo1Element.value); let cislo2 = parseFloat(cislo2Element.value); alert(cislo1 + cislo2); } tlacitkoElement.onclick = secti;
Řádek s obsluhou události kliknutí
(tlacitkoElement.onclick = secti;
) nyní přepíšeme na
následující:
tlacitkoElement.addEventListener("click", secti);
Funkci secti()
zde předáváme jako tzv.
callback, bez závorek.
Aplikace nyní funguje úplně stejně, ale splňuje dobré praktiky. Tlačítko v budoucnu může vyvolávat i další události.
Použití anonymní funkce
Ukažme si ještě pro úplnost, jak lze stávající kód upravit s
využitím anonymní funkce. Funkci secti()
tedy
smažeme a její tělo přesuneme do metody addEventListener()
.
Celý skript kalkulačky bude vypadat takto:
let tlacitkoElement = document.getElementById("tlacitko"); let cislo1Element = document.getElementById("cislo1"); let cislo2Element = document.getElementById("cislo2"); tlacitkoElement.addEventListener("click", function() { let cislo1 = parseFloat(cislo1Element.value); let cislo2 = parseFloat(cislo2Element.value); alert(cislo1 + cislo2); });
Shrňme si v krátkosti jeho jednotlivé části:
document
je objekt reprezentující celý obsah webové stránky. V JavaScriptu je to vstupní bod pro práci s DOM.getElementById()
je metoda objektudocument
, která vyhledá a vrátí element s konkrétnímid
zadaném v parametru. Výsledkem je reference na konkrétní element na stránce, v našem případě na tlačítko pro součet a na dvě pole pro zadání čísel.addEventListener()
je metoda, která "naslouchá" konkrétním událostem, jež se na daném elementu vyskytnou. Jako parametr ji zde zadáváme název události, kterou chceme sledovat (click
) a funkci, která se má po kliknutí vykonat.
Externí soubory
JavaScript bychom ideálně neměli v HTML souboru vůbec zahlédnout, protože míchat jazyky v jednom souboru je téměř vždy špatná praktika. Jistě již víme, že např. CSS soubory se píšou samostatně a z HTML se na ně poté odkazuje. Když to uděláme stejně s JavaScriptem, hovoříme o tzv. neobtruzivním JavaScriptu. Tímto výrazem označujeme kód, který v HTML nijak nepřekáží, ale je v samostatných souborech.
Doposud jsme pro jednoduchost psali náš kód v JavaScriptu přímo do HTML
stránky mezi tagy <script>
.
Odteď JavaScript budeme psát do externího souboru, na který z hlavní stránky odkážeme.
Ve složce projektu si tedy nyní vytvoříme podsložku js/
, v
ní vytvoříme soubor kalkulacka.js
a celý kód pro obsluhu
kalkulačky (bez tagů <script>
) do něj uložíme. Z HTML
jej úplně odstraníme. V hlavičce naší stránky pak přidáme
následující řádek, který na skript odkáže:
<script src="js/kalkulacka.js"></script>
Celý soubor index.html
bude vypadat takto:
<!DOCTYPE html> <html lang="cs-cz"> <head> <meta charset="UTF-8"> <title>Jednoduchá webová kalkulačka</title> <script src="js/kalkulacka.js"></script> </head> <body> <h1>Jednoduchá webová kalkulačka</h1> <input type="text" id="cislo1" size="5" /> + <input type="text" id="cislo2" size="5" /> <button id="tlacitko">Sečti!</button> <p> <a href="https://www.itnetwork.cz"> Výuková aplikace z ITnetwork.cz </a> </p> </body> </html>
A v souboru kalkulacka.js
budeme mít kód:
let tlacitkoElement = document.getElementById("tlacitko"); let cislo1Element = document.getElementById("cislo1"); let cislo2Element = document.getElementById("cislo2"); tlacitkoElement.addEventListener("click", function() { let cislo1 = parseFloat(cislo1Element.value); let cislo2 = parseFloat(cislo2Element.value); alert(cislo1 + cislo2); });
Pokud nyní vyzkoušíme naši kalkulačku, zjistíme, že se při sčítání čísel nic neděje. Je to proto, že se JavaScript spouští dříve, než je v HTML načtené tlačítko a vstupní pole. Výsledkem je chyba:

Problém vyřešíme přidáním atributu defer
k našemu
scriptu. Atribut defer
zajistí, že se JavaScript spustí
až po načtení celého HTML dokumentu, takže všechny prvky budou k
dispozici. Upravený kód vypadá takto:
<!DOCTYPE html> <html lang="cs-cz"> <head> <meta charset="UTF-8"> <title>Jednoduchá webová kalkulačka</title> <script src="js/kalkulacka.js" defer></script> </head> <body> <h1>Jednoduchá webová kalkulačka</h1> <input type="text" id="cislo1" size="5" /> + <input type="text" id="cislo2" size="5" /> <button id="tlacitko">Sečti!</button> <p> <a href="https://www.itnetwork.cz"> Výuková aplikace z ITnetwork.cz </a> </p> </body> </html>
Nyní už kalkulačka funguje správně.
Událost onload
Další způsob, jak zajistit, aby měl skript k dispozici všechny prvky
stránky, je vložit jej těsně před zavírací tag </body>
(bez defer
). V takovém případě se skript spustí ve
chvíli, kdy je HTML (DOM) už načtené, takže tlačítka a vstupy
jsou dostupné.
Pokud ale chceme, aby se kód spustil až ve chvíli, kdy je načtená
celá stránka včetně obrázků a stylů, můžeme využít
událost onload
, která se nachází na objektu
window
. Tím zajistíme spuštění kódu bez ohledu na to, v jaké
části HTML je vložený. K obsluze této události znovu využijeme
anonymní funkci:
window.onload = function() { let tlacitkoElement = document.getElementById("tlacitko"); let cislo1Element = document.getElementById("cislo1"); let cislo2Element = document.getElementById("cislo2"); tlacitkoElement.addEventListener("click", function() { let cislo1 = parseFloat(cislo1Element.value); let cislo2 = parseFloat(cislo2Element.value); alert(cislo1 + cislo2); }); };
Aplikace funguje stejně dobře jako předtím. Díky použití
window.onload
si nyní můžeme skript klidně přesunout i pod
začátek <body>
a kód se přesto spustí až ve chvíli,
kdy je celá stránka načtená.
Řešení pomocí posluchače událostí
I v tomto případě lze nahradit událost onload
metodou
addEventListener()
. Ekvivalentní zápis kódu výše s využitím
posluchače událostí pak vypadá takto:
window.addEventListener("load", function() { let tlacitkoElement = document.getElementById("tlacitko"); let cislo1Element = document.getElementById("cislo1"); let cislo2Element = document.getElementById("cislo2"); tlacitkoElement.addEventListener("click", function() { let cislo1 = parseFloat(cislo1Element.value); let cislo2 = parseFloat(cislo2Element.value); alert(cislo1 + cislo2); }); });
Posluchače jsme nastavili na událost load
. Skript
se tedy spustí až po načtení HTML stránky včetně externích
zdrojů, například obrázků. Protože zatím v aplikaci žádné
obrázky nemáme, mohli bychom použít také událost
DOMContentLoaded
, která čeká pouze na načtení
elementů DOM.
Dnešní kalkulačka je jako vždy ke stažení v archivu pod lekcí.
V příští lekci, Manipulace s DOM v JavaScriptu, budeme vybírat prvky DOM. Díky tomu pak můžeme vytvářet prvky nové, vkládat je do jiných, přesouvat, mazat a upravovat.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 261x (1.99 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript