Lekce 8 - 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

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Funkce v JavaScriptu, jsme se naučili používat funkce. 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 v tutoriálu ukážeme, jak se takové webové aplikace dělají a naprogramujeme si velmi jednoduchou kalkulačku v JavaScriptu.

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

Na obrázku 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 zadání čísel a jedno tlačítko <button> 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:

Your page
localhost

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 s 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.

let tlacitko = document.getElementById("tlacitko");
let cislo1 = document.getElementById("cislo1");
let 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á obsahy polí, sečte je jako 2 čísla a výsledek zobrazí funkcí alert() ve vyskakovacím okně.

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 např. 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í

let tlacitko = document.getElementById("tlacitko");
let cislo1 = document.getElementById("cislo1");
let 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. To 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álostí tentokrát využijeme anonymní funkce, které jsme se naučili v minulé lekci.

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

        tlacitko.onclick = function() {
                alert(parseInt(cislo1.value) + parseInt(cislo2.value));
        };
}

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.

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

<script src="js/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 složku, nabízí ze názvy skripty, scripts, js a podobně. U některých menších aplikací v kurzu toto zanedbáme. Dnešní kalkulačka je jako vždy ke stažení v příloze pro případ, že jste udělali někde chybu. V příští lekci, Manipulace s DOM v JavaScriptu, budeme pokračovat s manipulací DOM.


 

Stáhnout

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

 

 

Článek pro vás napsal Michal Žůrek - misaz
Avatar
Jak se ti líbí článek?
29 hlasů
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.
Miniatura
Předchozí článek
Funkce v JavaScriptu
Miniatura
Všechny články v sekci
Základní konstrukce jazyka JavaScript
Miniatura
Následující článek
Manipulace s DOM v JavaScriptu
Aktivity (7)

 

 

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

Avatar
Pluhtík
Člen
Avatar
Pluhtík:27. června 19:52
<!DOCTYPE html>

<html lang="cs-cz">

        <head>
                <meta charset="utf-8">
                <title>Kalkulacka, pole</title>
                <script src="javascript.js"></script>
        </head>

        <body>
                <h1>Kalkulacka</h1>
                <p> Number 1: <input type="text" id="n1" size="5" /> </p>
                <p> Number 2: <input type="text" id="n2" size="5" /> </p>
                <p> <button id="b1">Summation</button> </p>
                <p> <button id="b2">Substraction</button> </p>
                <p> <button id="b3">Multiplication</button> </p>
                <p> <button id="b4">Divison</button> </p>
                <p> <button id="b5">Power</button> </p>
        </body>

</html>
Editováno 27. června 19:53
 
Odpovědět 27. června 19:52
Avatar
Pluhtík
Člen
Avatar
Pluhtík:27. června 19:56

Number 1 jsem měl n1 místo n2, což byla chyba. Nyní místo klasické stránky vyskakuje to, co je na obrázku.
Jestliže smažu windows.onload function() {....} a upravím zarovnání, tak naskočí jen prázdná stránka

 
Odpovědět 27. června 19:56
Avatar
Michal Žůrek - misaz:27. června 20:22

Tak jak se to snažíš udělat je to složitější, musí se použít sofistikována funkce metoda bind. Správně je to

sum.onclick = after_Button.bind(null, 1, num1, num2);
sub.onclick = after_Button.bind(null, 2, num1, num2);
mul.onclick = after_Button.bind(null, 3, num1, num2);
div.onclick = after_Button.bind(null, 4, num1, num2);
pow.onclick = after_Button.bind(null, 5, num1, num2);

pak je jště tomu potřeba přizpůsobit

function after_Button(type, n1, n2) {
    document.write("<h1>Vysledek je: </h1>");
    if (type == 1)
        document.write(n1.value + n2.value);
    else if (type == 2)
        document.write(n1.value - n2.value);
    else if (type == 3)
        document.write(n1.value * n2.value);
    else if (type == 4)
        document.write(n1.value / n2.value);
    else
        document.write(Math.pow(n1.value, n2.value));
}

Jednodušší je to dělat jako ukazuje článek.

Odpovědět 27. června 20:22
Nesnáším {}, proto se jim vyhýbám.
Avatar
Pluhtík
Člen
Avatar
Odpovídá na Michal Žůrek - misaz
Pluhtík:27. června 20:24

Jsi si jistý, že má být n1.value atd.? Podívej se ještě jednou na můj kód - už jsem tam n1.value přímo přetypoval na integer.
Můžu vědět, co přesně dělá metoda bind?

 
Odpovědět 27. června 20:24
Avatar
Odpovídá na Pluhtík
Michal Žůrek - misaz:27. června 20:29

jo jsem si naprosto jist. Metodě nepředáváš hodnotu elementu, ale samotný element, proto při výpočtech musíš přečíst hodnotu z elementu, který ti to předalo v parametrech. Metoda bind vytváří kopii funkci a nahrazuje kontext volání za první parametr a další parametry pak odpovídají parametrům při volání. Kontext volání nepoužíváš, tak jsem tam dal null. Celkově to je poměrně složitý přístup.

Odpovědět 27. června 20:29
Nesnáším {}, proto se jim vyhýbám.
Avatar
Odpovídá na Pluhtík
Michal Žůrek - misaz:27. června 20:34

problém je v tom, že ty jsi tu funci nenastavoval jako událost ale ihned si ji volal.

sleduj rozdíl mezi tímto:

aaaa.onclick = funkce;

a

aaaa.onclick = funkce();

to první nastaví funkci jako událost kliknutí, ale nezavolá ji. Zavolá ji až jádro prohlížeče v okamžiku kdy klikneš na tlačítko. V druhém případě to funci zavolá hned a jako událost onclick to nastaví to, co funkce vrátí. Tvá funkce nevrátí nic, takže to žádnou událost nenastaví. To co chceš je případ 1, jenže tím že tam nemáš žádné závorky, potažmo ani parametry, tak si je tam musíš "dolepit" a přesně toto dělá funkce bind. Ona ti je přilepí aby tam byly a zároveň jsi to nevolal hned.

Odpovědět 27. června 20:34
Nesnáším {}, proto se jim vyhýbám.
Avatar
Pluhtík
Člen
Avatar
Odpovídá na Michal Žůrek - misaz
Pluhtík:27. června 20:37

Ano, já vím, došlo mi to.

Tak jinak. Není snad hodnotou elementu string? A jestli ano, tak n1.value mi nepomůže dosáhnout kalkulačky (přinejmenším ne takové kalkulačky, kterou bych mohl reálně použít na práci s čísly), nebo se mýlím?

Já mám v kódu

num1 = document.getElementById('n1');
num2 = document.getElementById('n2');
num1 = parseInt(num1.value);
num2 = parseInt(num2.value);

Aha, tak už vidím, proč jsem tě zmátl. Já omylem nepoužíval num1, num2 v té funkci, ale pouze n1, n2.
Bude tedy můj kód korektní za předpokladu, že doplním metodu bind a n1, n2 uvnitř funkce nahradím proměnnýma num1 a num2?

 
Odpovědět 27. června 20:37
Avatar
Pluhtík
Člen
Avatar
Odpovídá na Pluhtík
Pluhtík:27. června 20:47

Blbost, to ty jsi zmátl mě :D n1 a n2 jsou parametry funkce. Takže s num1 a num2 reálně pracuji, protože jsem je zadal jako parametry n1 a n2.

 
Odpovědět 27. června 20:47
Avatar
Odpovídá na Pluhtík
Michal Žůrek - misaz:27. června 21:01

aha, takže odmaž

num1 = parseInt(num1.value);
num2 = parseInt(num2.value);

a ve výpočtu nahraď n1.value za parseInt(n1.value)

Odpovědět  +1 27. června 21:01
Nesnáším {}, proto se jim vyhýbám.
Avatar
Pluhtík
Člen
Avatar
Odpovídá na Michal Žůrek - misaz
Pluhtík:27. června 21:04

Děkuji, udělal jsem to asi minutu předtím :) každopádně s metodou bind jsi mi pomohl (vím, že to první poděkování může vyznít ironicky, není to ironie, myslím to vážně ;) )

 
Odpovědět 27. června 21:04
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 28. Zobrazit vše