DOM – objektový model dokumentu 5.

Dnes se začneme zabývat tématem, které ukazuje sílu a možnosti DOM – vytvářením nových uzlů (elementů, atributů, textu) a jejich přidáním do dokumentu.

V minulých dílech jsme se seznámili s DOM a naučili se procházet „stromem“ objektů, který vznikne jako reprezentace HTML stránky nebo XML dokumentu. Ukázali jsme si, že některé vlastnosti objektů umožňují i změnu textového obsahu elementů či atributů. Pomocí DOM však můžeme dosáhnout mnohem více – modifikovat strukturu celého dokumentu doslova „k nepoznání“, přidávat, duplikovat či mazat v podstatě jakoukoliv část dokumentu. Právě těmto možnostem DOM se budeme nyní věnovat.

Vytvoření nového elementu, atributu, textového obsahu a přidání do dokumentu

Začněme příkladem, který posléze rozebereme. Příklad si samozřejmě můžete vyzkoušet.

Jak se můžete sami přesvědčit, po kliknutí na odkaz „Klikněte pro vytvoření nového odkazu !“ se pod tímto odkazem objeví nový s textem „DOM Compatibility Table“. Ve zdrojovém kódu stránky je vidět, že žádný další odkaz tam „schovaný“ (např. pomocí css vlastnosti display: none, nebo visibility: hidden) opravdu není:

<html>
<head>
<title>vytváření nových uzlů</title>
</head>
<body>
<a href="javascript:vytvorNovyOdkaz()">Klikněte pro vytvoření nového odkazu!</a>
<br>
</body>
</html>

Když vyloučíme zázrak, nezbývá než uvěřit, že to celé má na svědomí skutečně DOM :). Jistě jste zvědavi, jak se toho dá dosáhnout.

Rozeberme si tedy podrobně celou funkci, která má vytvoření nového odkazu na svědomí:

function vytvorNovyOdkaz() {
  var novy_odkaz = document.createElement(„a“);
  var obsah_odkazu = document.createTextNode("DOM Compatibility Table");
  novy_odkaz.setAttribute("href", "http://www.xs4all.nl/~ppk/js/version5.html");
  novy_odkaz.appendChild(obsah_odkazu);
  var body = document.getElementsByTagName(„body“)[0];
  body.appendChild(novy_odkaz);
}

Na první řádce této funkce vytvoříme nový element <a> a uložíme ho do proměnné novy_odkaz. O vytvoření nového elementu se postarala metoda createElement() používaná ve spojení s objektem document. Této metodě předáváme v parametru jméno elementu, který chceme vytvořit. Nyní tedy máme v proměnné novy_odkaz uložen objekt, který reprezentuje nově vzniklý element <a>. Upozorňuji na to, že v této chvíli tento objekt ještě není součástí stromu DOM objektů – zatím je pouze vytvořen a na své zařazení na správné místo teprve čeká.

Na další řádce vytváříme uzel typu text, který uložíme do proměnné obsah_odkazu. Textový uzel vznikne, pokud použijeme metodu createTextNode(). Opět se jedná o metodu objektu document. Jako parametr se předává textový obsah, který tento uzel ponese. V našem případě je to text „DOM Compatibility Table“. Opět platí, že náš nově vytvořený textový objekt není ještě součástí stromu DOM objektů, tj. není zařazen do dokumentu.

Co bude následovat? Jistě tušíte, že pořádný odkaz nemůže nikdy existovat bez atributu href, jenž určuje URL, na kterou vede odkaz. Tuto nesrovnalost napravíme na dalším řádku. Na element <a> uložený v proměnné novy_odkaz aplikujeme metodu setAttribute(), která se postará o nastavení atributu href na správnou hodnotu. Jméno atributu, který chceme nastavit, se předává jako první parametr této metody. Druhý parametr nese obsah (hodnotu) atributu.

Nyní tedy máme v jedné proměnné uložen element s nastaveným atributem a v další proměnné zase textový objekt, který se má stát obsahem tohoto elementu. Stojíme tedy před úkolem, jak tento textový objekt „přilepit“ do elementu. To nám na dalším řádku vyřeší metoda appendChild, kterou aplikujeme na objekt novy_odkaz. V parametru této metody se předává jméno uzlu, který se má „přilepit“ do elementu – přesněji řečeno, který se má stát dítětem elementu.

Postoupili jsme tedy o další kousek a element <a> uložený v proměnné novy_odkaz už má nejen nastaven nutný atribut href, ale obsahuje i text. Čeká nás tedy poslední krok – přidání elementu do dokumentu. Použijeme k tomu stejný postup jako při přidání textového uzlu do našeho nového odkazu – tedy metodu appendChild(). Nejprve si ale musíme vybrat, kam náš odkaz umístíme. Vzhledem k jednoduchosti naší HTML stránky v příkladu si vystačíme s prostým přilepením do elementu <body>. Pomocí dobře známé metody getElementsByTagName() uložíme do proměnné body stejnojmenný element. Na posledním řádku konečně přidáme pomocí zmíněné metody appendChild() náš nový odkaz do elementu <body>.

Všimněte si, že pokud element, do něhož přidáváme další dítě, již nějaké děti má, stává se nově přidaný objekt posledním dítětem (lastChild).

Dodejme, že pořadí jednotlivých akcí v tomto skriptu můžeme změnit, tj. není podmínkou, abychom napřed nastavili atribut elementu a přidali textový obsah a nakonec teprve celý fragment přidali do dokumentu. Bez potíží můžeme element „přilepit“ do dokumentu hned po vytvoření, teprve poté nastavovat hodnoty jeho atributů či textového obsahu. Mohou se ovšem vyskytnout situace, kdy následné nastavení atributů elementu po jeho zařazení do dokumentu bude problematické (o tom se dočtete v dalším textu), proto je lepší držet se pravidla, že přidání do dokumentu má být provedeno vždy až nakonec.V každém případě však nesmíme zapomenout na přidání uzlu do dokumentu a mít na paměti, že vytvořený uzel se nestává součástí dokumentu automaticky.

Poznámka k metodě setAttribute() – teoreticky lze samozřejmě nastavovat jakékoliv atributy, nicméně v praxi je potřeba vyvarovat se nastavování atributu style. Důvod je ten, že tento postup nepřináší v IE 5 žádný efekt, tj. změnu stylu. Vzhledem k tomu, že je určitě lepší nastavit styl určitého elementu pomocí objekt.style.vlastnost=“hodnota“ (např. novy_odkaz.style.fontColor=“blue“, podrobněji v dalších dílech seriálu), není nutné se s důsledky tohoto „bugu“ nijak potýkat. Další omezení pocítíte, pokud budete chtít měnit atribut type u elementu <input> (pomocí metody setAttribute() je možné nejen nastavit nové, ale i měnit již nastavené atributy). Tento postup bude fungovat jen v Mozille. Nastavení atributu type u nově vytvořeného elementu <input> samozřejmě fungovat bude i v Internet Exploreru – ale pozor na to, aby tento atribut byl nastaven dříve, než element přidáme do dokumentu. V opačném případě se v IE setkáme s chybovou hláškou. Pokud je potřeba změnit typ elementu <input>, je nutné element vytvořit znovu a nahradit ten starý na původním místě. Jak nahradit element se dozvíte v dalším textu.

Další manipulace – klonování, přemísťování a nahrazování uzlů

Pojďme si ukázat další možnosti, které se nám nabízejí při manipulaci s uzly. Opět si vše ukážeme na příkladu. Naši HTML stránku si trochu rozšíříme – tentokrát budeme mít 3 odkazy, každý z nich volá jednu funkci.

<html>
<head>
  <title>klonování, přemísťování a nahrazování uzlů</title>
</head>

<body>
<div style="background-color:lightblue">
----blok----
</div>
<div id="odkazy">
  <a href="javascript:pridejTextPred()">Klikněte pro přidání textu před do modreho bloku pred ----blok---- !</a>
  <br>
  <a href="javascript:klonujTextZa()">Klikněte pro naklonování modreho bloku, a přidání za odkazy !</a>
  <br>
  <a href="javascript:nahrad()">Klikněte pro nahrazení tohoto odkazu prvním odkazem!</a>
</div>
</body>
</html>

Přidání nového uzlu před jiný uzel – metoda insertBefore()

function pridejTextPred() {
  var novy_blok = document.createElement(„div“);
  var novy_text = document.createTextNode("nejaky text...");
  novy_blok.appendChild(novy_text);
  var prvni_blok = document.getElementsByTagName(„div“)[0];
  var prvni_dite = prvni_blok.firstChild;
  prvni_blok.insertBefore(novy_blok, prvni_dite);
}

Funkce pridejTextPred() se aktivuje při kliknutí na odkaz „Klikněte pro přidání textu do modrého bloku před text ----blok---- !“ a přidává text "nejaky text..." do světlemodrého bloku.

První 3 řádky zřejmě není potřeba příliš vysvětlovat. Vytvoříme nový element <div>, dále vytvoříme textový uzel s textem „nejaky text“ a „vlepíme“ ho do elementu, který máme uložen v proměnné novy_blok. Na 4. řádku uložíme do proměnné první_blok první element <div> z naší HTML stránky (jedná se o ten, který obsahuje text „---blok---„ a má světle modré pozadí). Poté do proměnné první_dite uložíme první dítě tohoto elementu.

Teprve na posledním řádku je něco nového – metoda insertBefore(). Tato metoda má 2 parametry – první je uzel, který budeme vkládat, a druhý je uzel, před který budeme vkládat. V našem případě vložíme před uzel první_dite uzel novy_blok. Jinými slovy, po vložení bude uzel první_dite následujícím sourozencem (next sibling) uzlu novy_blok. Uzel, před který budeme vkládat, musí být dítětem elementu, na který metodu aplikujeme. Vidíte, že v našem případě je první_dite skutečně dítětem elementu první_blok. Metoda insertBefore() je doplňkem k metodě appendChild(), která vždy přidává nové dítě naopak až za všechny ostatní děti.

Klonování uzlů – metoda cloneNode()

function klonujTextZa() {
  var body = document.getElementsByTagName(„body“)[0];
  var prvni_blok = document.getElementsByTagName(„div“)[0];
  var klon = prvni_blok.cloneNode(true);
  klon.style.backgroundColor="yellow";
  body.appendChild(klon);
}

Funkce klonujTextZa() ukazuje „naklonování“ celého prvního (modrého) bloku se všemi dětmi a tento klon připojí na konec dokumentu. Je volána po kliknutí na odkaz „Klikněte pro naklonování modrého bloku a přidání za odkazy !“.

První 2 řádky opět nepřinášejí nic neznámého, pouze ukládají do proměnné body element <body> a do proměnné první_blok již zmíněný element <div> (ten s modrým pozadím).

Na další řádce dochází k procesu klonování – do proměnné klon se uloží klon (nebo česky řečeno kopie) objektu první_blok. Klonování zajišťuje metoda cloneNode() aplikovaná na objekt, který chceme „zkopírovat“. Metodě se v parametru předává buď true, pokud má být zkopírováno vše včetně všech dětí a potomků, nebo false, pokud chceme zkopírovat pouze samotný element bez potomků. V našem příkladu klonujeme celý uzel i s potomky, což jsou všechny vnořené elementy <div> s textem (jejich počet závisí na tom, kolik jich bylo přidáno předtím klikáním na první odkaz) i text ---blok---. Poté je našemu klonu nastaveno žluté pozadí, abychom ho odlišili od jeho bleděmodrého „vzoru“. Nakonec je přidán na konec dokumentu.

K metodě cloneNode() je potřeba dodat jedno upřesnění – dle W3C normy by klonovaný uzel neměl kopírovat ovladače událostí (např. pokud element, který je klonován, má nastaven atribut onMouseOver, jeho klon by na najetí myší nijak reagovat neměl), nicméně Internet Explorer (a taktéž Konqueror) tyto ovladače událostí kopíruje také.

Nahrazení uzlu jiným uzlem – metoda replaceChild()

function nahrad() {
  var blok_odkazu = document.getElementById(„odkazy“);
  var prvni_odkaz = document.getElementsByTagName(`a`)[0];
  var treti_odkaz = document.getElementsByTagName(`a`)[2];
  blok_odkazu.replaceChild(prvni_odkaz, treti_odkaz);
}

Funkce nahrad() ukazuje nahrazení třetího odkazu s textem „Klikněte pro nahrazení tohoto odkazu prvním odkazem!“ (tedy toho, jehož prostřednictvím je sama aktivována) prvním odkazem.

Na prvních 3 řádcích si uložíme do proměnné blok_odkazu element nadřazený všem třem odkazům (tedy jejich rodič) a do proměnných první_odkaz a treti_odkaz první a třetí element <a>. Nahrazení třetího odkazu prvním se děje na další řádce. Stará se o něj metoda replaceChild(). Syntaxe této metody je podobná metodě insertBefore(). Metoda má dva parametry – první parametr je uzel, který nahradí uzel uvedený jako druhý parametr. Metoda se aplikuje na rodič uzlu, který bude nahrazen. Jak si můžete sami vyzkoušet, výsledným efektem je to, že první odkaz „odcestuje“ ze své původní pozice na začátku a nahradí tak třetí odkaz, který tímto zmizí, zcela nahrazen prvním odkazem.

Při používání této metody se samozřejmě nemusíme omezovat na manipulace mezi dětmi jednoho uzlu – klidně můžeme uzel textového typu nahradit nově vytvořeným fragmentem elementů.

Tolik tedy dnes o vytváření nových uzlů a manipulaci s nimi. V příštím dílu budeme v tomto tématu pokračovat. Ukážeme si některé další metody pro manipulaci s uzly a jejich textovým obsahem, taktéž si představíme pár specifických rozšíření od Microsoftu (jak už je u něj zvykem…) a na závěr dílu je připravena další shrnující tabulka.

Váš názor Další článek: BMW řady 7 používá Windows CE

Témata článku: Software, Internet, Programování, Internet Explorer, Head, Dítě, Nový typ, Nová metoda, Nové dítě, Nový odkaz, Model S, Původní objekt, DOM, První dítě, Dok, Následné nastavení, První případ, Doma, První parametr, Mode, První funkce, Objekt, CSS vlastnost, Následné uložení, Model


Určitě si přečtěte

Jak sestavit rodokmen. Z informací, které jsou na internetu

Jak sestavit rodokmen. Z informací, které jsou na internetu

Podrobný návod, jak hledat ve starých matrikách informace o předcích a nemuset při tom ani vstát od počítače. Základy internetové genealogie.

Marek Lutonský | 59

Filmové pirátství asi jen tak nezmizí. Když už musíte, stahujte bezpečně v Seedru

Filmové pirátství asi jen tak nezmizí. Když už musíte, stahujte bezpečně v Seedru

** Máme HBO Go, máme Netflix... ** Ale stejně krademe filmy a seriály ** Když už musíte, stahujte torrenty bezpečně v Seedru

Jakub Čížek | 141

Epic chce rozbít monopol Play Storu a App Storu. Nastražil trik s hrou Fortnite a žaluje Google i Apple

Epic chce rozbít monopol Play Storu a App Storu. Nastražil trik s hrou Fortnite a žaluje Google i Apple

** Apple a Google odstranili z obchodů s aplikacemi hru Fortnite ** Její vývojáři nejprve přichystali parodické video ** V žalobách viní obě firmy z monopolního chování

Karel Kilián | 135


Aktuální číslo časopisu Computer

Velký test fitness náramků

Levné záložní zdroje

Jak si zabezpečit domov

Nejlepší monitory na trhu