8. díl - Základy práce s DOM a události v JavaScriptu

JavaScript Základní konstrukce Základy práce s DOM a události v JavaScriptu

V minulém dílu našeho seriálu jsme se naučili používat funkce v JavaScriptu. Až doteď jsme se úspěšně vyhýbali hlavnímu využití JavaScriptu, kterým je manipulace s obsahem webové stránky. Ta zahrnuje čtení a změnu obsahu stránky v reakci na nějaké akce od uživatele (např. stisknutí tlačítka vypočítá příklad nebo zobrazí/skryje určitou část webu). Takovým aktivním webům se potom říká spíše webové aplikace, než webové stránky. Na události reagujeme pomocí funkcí, které již ovládáme. Dnes si ukážeme, jak se takové webové aplikace dělají a naprogramujeme si velmi jednoduchou kalkulačku.

Co je to DOM

DOM je zkratka pro Document Object Model. Jedná se o strom elementů (objektů), ze kterých je HTML stránka složena. Objekty v DOM můžeme pomocí JavaScriptu měnit a tím samozřejmě měníme výslednou webovou stránku. Představme si nějaký jednoduchý HTML dokument.

<!DOCTYPE html>
<html>
<head>
    <title>Moje webová stránka</title>
        <meta charset="utf-8" />
</head>
<body>
        <nav>
                <img src="logo.png" alt="logo" />
                <ul>
                        <li>Reference</li>
                        <li>Fotogalerie</li>
                </ul>
        </nav>
        <main>
                <article>
                        <p>Ahoj</p>
                        <p>Obrovský</p>
                        <p>Světe</p>
                </article>
        </main>
</body>
</html>

JavaScript tedy dokument vidí jako strom objektů. Značně zjednodušeně bychom si DOM pro dokument výše mohli představit následovně:

DOM v JavaScriptu

V návrhu chybí nějaké uzly (celý element head, chybí tam i tzv. textové uzly, což je samotný text elementu, např. v elementu p), nicméně vidíme jak JavaScript stránku vnímá. Po stromu se můžeme pohybovat a do jeho větví přidávat nové elementy, měnit jejich obsah nebo je mazat. V naší kalkulačce budeme zatím z DOM vybírat prvky pouze podle jejich ID. Kdykoli, kdy chceme pracovat v JavaScriptu s DOM, odkazujeme se na objekt document, který má pro to určené metody.

Příprava HTML stránky pro kalkulačku

Pro naši kalkulačku si vytvořme opravdu jednoduchou webovou stránku, která bude obsahovat 2 elementy input pro čísla a jedno tlačítko pro provedení výpočtu. Kalkulačka bude umět čísla jen sčítat, ale to nás zatím nebude trápit.

<!DOCTYPE html>
<html lang="cs-cz">

<head>
        <meta charset="UTF-8">
        <title>Jednoduchá webová kalkulačka</title>
</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>
        <script type="text/javascript">
                // Sem budeme psát náš kód
        </script>
</body>

</html>

Výsledná stránka vypadá asi takto:

Webová kalkulačka v JavaScriptu

Všimněte si, že je náš skript vložený až pod inputy a tlačítkem. Je tomu z toho důvodu, že kdybychom ho vložili nad tyto elementy, spustil by se ve chvíli, kdy ve stránce formulářové prvky ještě nejsou a nemohl by je tak používat.

Výběr elementu na základě id

Pro výběr elementu na základě id se hodí metoda (funkce) getElementById, která bere jako parametr (v závorkách) textový řetězec, což je id vybíraného elementu. Naše kalkulačka bude pracovat s vytvořeným tlačítkem i inputy na číslo, proto si je všechny načteme do proměnných.

var tlacitko = document.getElementById("tlacitko");
var cislo1 = document.getElementById("cislo1");
var cislo2 = document.getElementById("cislo2");

Každý element má nějaké vlastnosti, elementy input (ve kterých máme čísla) například mají vlastnost value, ve které je hodnota, kterou do tohoto pole uživatel zadal. Vytvořme si funkci secti(), která si pomocí výše vytvořených proměnných získá obsah polí, sečte ho jako 2 čísla a výsledek zobrazí funkcí alert() jako vyskakovací okno.

function secti() {
        alert(cislo1.value + cislo2.value);
}

Události

Kdykoliv se v naší aplikaci něco stane (uživatel něco někam zadá, někam klikne, dojde k chybě a podobně...), JavaScript začne spouštět tzv. obsluhy událostí. Události nalezneme jako vlastnosti na jednotlivých elementech z DOM, začínají vždy na on, např. onclick je událost kliknutí. Právě tu si vybereme na našem tlačítku a uložíme do ní naši funkci secti. To způsobí, že se funkce zavolá pokaždé, když se na tlačítko klikne.

tlacitko.onclick = secti;

Vlastností je samozřejmě více, lze obsluhovat třeba pohyb myši na tlačítku a několik dalších věcí. Všimněte si, že když někam funkci ukládáme, neuvádíme závorky. Nyní máme kalkulačku téměř hotovou. Zdrojový kód (JavaScriptová část) celé kalkulačky je následující

var tlacitko = document.getElementById("tlacitko");
var cislo1 = document.getElementById("cislo1");
var cislo2 = document.getElementById("cislo2");

function secti() {
        alert(cislo1.value + cislo2.value);
}

tlacitko.onclick = secti;

Jak jste jistě zjistili, naše kalkulačka hodnoty z inputů sčítá jako textové řetězce. Což je logické, protože se o text jedná. Po zadání 10 + 20 tedy vypíše 1020 namísto 30. Oprava bude jednoduchá, využijeme funkce parseInt, která nám text převede na číslo. Funkci secti() upravíme do následující podoby:

function secti() {
        alert(parseInt(cislo1.value) + parseInt(cislo2.value));
}

Naše kalkulačka nyní funguje dle očekávání. Abychom ji dovedli k dokonalosti, provedeme ještě 2 úpravy.

Událost onload

Abychom se nemuseli strachovat jestli je skript na konci stránky a jestli se spouští ve chvíli, když je stránka kompletně načtená, využijeme události onload. Ta se nalézá na objektu window a spustí se ve chvíli, kdy je celá stránka načtená (i včetně obrázků a podobně). Upravíme náš kód tak, aby se spustil právě po načtení stránky bez ohledu na to v jaké části stránky je vložený. K obsluze události tentokrát využijeme anonymní funkci, které jsme se naučili v minulé lekci.

window.onload = function() {
        var tlacitko = document.getElementById("tlacitko");
        var cislo1 = document.getElementById("cislo1");
        var cislo2 = document.getElementById("cislo2");

        function secti() {
                alert(parseInt(cislo1.value) + parseInt(cislo2.value));
        }

        tlacitko.onclick = secti;
}

Aplikace funguje stejně dobře jako předtím. Můžete si zkusit skript přesunout třeba pod začátek body, aplikace bude fungovat stejně, protože se kód spustí až ve chvíli, když je celá stránka načtená.

Externí soubory

JavaScript bychom ideálně neměli v souboru s příponou HTML vůbec zahlédnout, protože míchat jazyky v jednom souboru je téměř vždy špatná praktika. Jistě víte, že např. CSS soubory se píší samostatně a do HTML se na ně poté odkazuje. Když to uděláme stejně s JavaScriptem, hovoříme o tzv. neobtruzivním JavaScriptu, tedy kódu, který v HTML nijak nepřekáží, ale je v samostatných souborech.

Celý kód výše uložme do souboru kalkulacka.js (již bez elementu script) a z HTML kódu element script úplně odstraníme. Do hlavičky stránky (elementu <head>) potom přidáme pouze následující řádku, která na skript odkáže:

<script type="text/javascript" src="kalkulacka.js"></script>

Skripty se někdy alternativně vkládají také těsně před </ body>. U větších aplikací bychom si na javascriptové soubory měli ideálně vytvořit nějakou složku, nabízí ze názvy skripty, scripts, js a podobně. Dnešní kalkulačka je jako vždy ke stažení v příloze pro případ, že jste udělali někde chybu. Příště budeme pokračovat s manipulací DOM.


 

Stáhnout

Staženo 362x (2.41 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

  Aktivity (1)

Článek pro vás napsal Michal Žůrek (misaz)
Avatar
Autor se věnuje tvorbě aplikací pro počítače, mobilní telefony, mikroprocesory a tvorbě webových stránek a webových aplikací. Nejraději programuje ve Visual Basicu a TypeScript. Ovládá HTML, CSS, JavaScript, TypeScript, C# a Visual Basic.

Jak se ti líbí článek?
Celkem (15 hlasů) :
55555


 


Miniatura
Předchozí článek
Cvičení k 7. lekci JavaScriptu
Miniatura
Všechny články v sekci
Základní konstrukce jazyka JavaScript
Miniatura
Následující článek
Manipulace s DOM v JavaScriptu

 

 

Komentáře
Zobrazit starší komentáře (5)

Avatar
Ondřej Krsička
Redaktor
Avatar
Ondřej Krsička:

Typ inputu by byl lepší number než text. Ale je to jedno.

 
Odpovědět 20.9.2015 9:35
Avatar
grygule
Člen
Avatar
grygule:

Mám jednu otázku. Když se stránka načte, tak provede funkci, která je uložená v window.onload, jakmile je stránka načtená, tak se funkce window.onload spustí a proběhne ? Ale když proběhne, kde v programu se pak nacházím ? Totiž když pak zmáčknu tlačítko, aktivuje se tlačitko.onclick, ale jak se tam program dostane, když funkce window.onload už proběhla ?

 
Odpovědět 21.9.2015 18:42
Avatar
Odpovídá na grygule
Michal Žůrek (misaz):

nijak. Když program skončí provádění funkce window.onload (popř pár dalších, které se starájí o načítání obsahu), nenastává "nic". Prostě není nikde, nic nedělá, dokud ho k tomu něco nepřinutí. Třeba kliknutí na tlačítko ho k tomu právě přinutí.

Odpovědět 21.9.2015 18:45
Nesnáším {}, proto se jim vyhýbám.
Avatar
Odpovídá na grygule
miroslav.jojo:

window.onload ak sa nemylim tak sluzi na to aby sa spustil po nacitani vsetkych elementy v DOM-e. Pretoze kyby sa script spustil este pred tym jak by sa nacital cely DOM tak by sa ti mohlo stat ze script by nepoznal napriklad input s id="cislo2" a potom by ti to nic neviratalo

Odpovědět 12.11.2015 7:34
S programovanim len zacinam...som uplna lama!!!
Avatar
 
Odpovědět 24. března 17:57
Avatar
Michal Vlasák:

Ahoj, jakto, že je funkce secti() bez argumentů. Očekával jsem, že tam budeme nějaké dávat, protože nechápu, jak je možné, že tato funkce "zná" proměnné cislo1 a cislo2.
Děkuji za vysvětlení.

 
Odpovědět 13. dubna 11:50
Avatar
Taskkill
Redaktor
Avatar
Odpovídá na Michal Vlasák
Taskkill:

Dobře, koukni se kde je funkce secti() deklarovaná, uvnitř jiné funkce, v javascriptu existuje něco čemu se říká vareable context, jinými slovy tato funkce je v podstatě dcerou vnější funkce, jako taková má tedy právo sahat na proměnné z matky aniž by musela sama matka být v té době dostupná... Má to řadu výhod, ale trochu to kazí přehlednost kódu v začátcích, Vem to jako fakt. Na druhou stranu, když deklaruješ v jiných jazycích cyklus, nebo if taky je zevnitř vidět ven, no a díky tomu, že javascript ti dovolí vytvořit funkci uvnitř funkce, může vnitřní funkce vidět taky ven. Rozumíš?

 
Odpovědět  +2 13. dubna 13:43
Avatar
Odpovídá na Taskkill
Michal Vlasák:

Ahoj, moc ne, protože, když jsme měli tenhle kód:

var tlacitko = document.getElementById("tlacitko");
var cislo1 = document.getElementById("cislo1");
var cislo2 = document.getElementById("cislo2");

function secti() {
        alert(cislo1.value + cislo2.value);
}

tlacitko.onclick = secti;

tak ta funkce secti() dcera žádné funkce ještě nebyla a fungovalo to taky.

 
Odpovědět 14. dubna 8:08
Avatar
Taskkill
Redaktor
Avatar
Odpovídá na Michal Vlasák
Taskkill:

Ale ovšem že funkce secti() byla dcerou, tentokrát ne jiné funkce ale globálního objektu window, nebolí object Global, do kterého patří všechno, pokud nestanovíš jinak ... Doporučuji tohle se pro začátek naučit jako fakt a až budeš mít v JS nějakou praxi ono to do sebe všechno dozapadne samo neboj. Javascript je v tomhle zvláštní a není snadný si všechno představit hned na začátku, chce to abys prošel trochu objekty a experimentoval s funkcemi ... Teď už by to ale mohlo být jasnější ...

 
Odpovědět  +1 14. dubna 9:51
Avatar
Odpovídá na Michal Žůrek (misaz)
Libor Šimo (libcosenior):

Na tejto stránke:

<!DOCTYPE html>
<html>
<head>
    <title>Moje webová stránka</title>
        <meta charset="utf-8" />
</head>
<body>
        <nav>
                <img src="logo.png" alt="logo" />
                <ul>
                        <li>Reference</li>
                        <li>Fotogalerie</li>
                </ul>
        </nav>
        <main>
                <article>
                        <p>Ahoj</p>
                        <p>Obrovský</p>
                        <p>Světe</p>
                </article>
        </main>
</body>
</html>

chcem vložiť element "p" do article.
Toto mi funguje (ako rodiča berie "body")
p.appendChild(bo­dy);
ale toto nie (ako rodiča mi "article" neberie, nie je definovaný)
p.appendChild(ar­ticle);
Ako ho mám definovať?

Mám takýto kód:

function vytvorRiadok(text, rodic) {
         var p = document.createElement("p");
         p.textContent = text;
         rodic.appendChild(p);

         return p;
}

function vytvorVsetkyRiadky() {
         vytvorRiadok("koleso", document.article);
}

window.onload = function() {
         vytvorVsetkyRiadky();
         console-log(vytvorVsetkyRiadky());
}
Odpovědět 20. dubna 9:36
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 15. Zobrazit vše