Kretanje kroz DOM stablo elemenata
Pošto su objekti web dokumenta aranžirani u hijerarhijsku strukturu tipa stablo, sami po sebi, ti objekti nam moraju omogućiti kretanje kroz tu strukturu. Na svakoj "grani", objekti (koji u dokumentu idu jedan za drugim na istom hijerarhijskom nivou) su vezani u dvostruku listu. To znači da svaki objekat poseduje referencu na sledeći, ali i prethodni objekat.
E, sad, u stablu svaki "čvor" na grani, odnosno objekat u listi, može imati sopstvenu "granu", tj. podlistu objekata. Opet, svaki od tih podobjekata može imati svoje podobjekte i tako u nedogled (ok, onoliko koliko web čitač može da "izdrži"). Na taj način dobijamo stablo strukturu. Svaki objekat takođe mora da poseduje reference na svoje podređene objekte, kao i referencu na svoj nadređeni objekat.
Objekti
Kao što znamo, ovi čvorovi mogu biti objekti različitih tipova - od "najapstraktnijeg" Node objekta, preko elementa i HTML elementa pa do konkretnih HTML elemenata. Svaki elemenat jeste Node, ali nije svaki Node istovremeno i elemenat.
Objekat Node
Pošto je kretanje kroz strukturu bazična potreba koju moraju da zadovolje svi čvorovi, implementirano je na osnovnom nivou - za svaki Node objekat. Ovde su navedena svojstva i metodi Node objekta koji nam trebaju.
Nadređeni objekat | |
---|---|
ownerDocument | Referenca na Document kome pripada objekat |
parentNode | Referenca na nadređeni objekat |
parentElement | Referenca na nadređeni objekat i to samo ako je Element |
Vezani objekti | |
previousSibling | Referenca na prethodni objekat na istom hijerarhijskom nivou |
nextSibling | Referenca na sledeći objekat na istom hijerarhijskom nivou |
Podobjekti | |
hasChildNodes() | Vraća true ako objekat ima podobjekte |
childNodes | Lista podređenih objekata |
firstChild | Referenca na prvi podobjekat |
lastChild | Referenca na poslednji podobjekat |
Objekat Element
Specifična svojstva koja se dodaju web objektu ako je on elemenat. Elementi su HTML elementi, zatim SVG, XML, MathML elementi. Praktično je to sve što nas zanima, osim čistog teksta koji spada u običan objekat.
Iako sve što nam treba možemo da postignemo koristeći samo mogućnosti Node objekta, bilo bi to malo naporno i nepraktično. Zbog toga postoje svojstva i metodi objekta Element, koji služe da olakšaju život programerima, pošto u velikoj većini slučajeva radimo samo sa elementima.
Vezani elementi | |
---|---|
nextElementSibling | Referenca na sledeći elemenat na istom hijerarhijskom nivou |
previousElementSibling | Referenca na prethodni elemenat na istom hijerarhijskom nivou |
Podelementi | |
childElementCount | Broj podelemenata |
children | Lista podelemenata |
firstElementChild | Referenca na prvi podelement |
lastElementChild | Referenca na poslednji podelement |
Svaki elemenat ima i ova svojstva i sve što imaju i obični objekti tipa Node.
Svojstva i metodi
Za kretanje kroz stablo (između nivoa hijerarhije), odnosno kroz listu (na istom nivou hijerarhije), najpre koristimo svojstva koja predstavljaju reference na određene elemente. Kroz celu hijererhiju se prolazi rekurzivno.
parentNode
Referenca parentNode pokazuje na nadređeni objekat, bez obzira kog je tipa (bilo Node, bilo Element - mada će u 99% slučajeva to biti elemenat).
<div>
<p>...</p>
</div>
Dakle u situaciji kao u okviru, pasus.parentNode predstavlja div elemenat.
Svojstvo parentElement se takođe odnosi na nadređeni objekat, ali samo ako je tipa Element - u suprotnom će imati vrednost null. Ovo svojstvo je najpre postojalo isključivo u Internet Exploreru, a kasnije je uvedeno i u ostale web čitače. U normalnim okolnostima ćemo koristiti samo parentNode.
Svojstvo ownerDocument predstavlja referencu na dokument koji sadrži dati element. Kada uobičajeno radimo sa HTML elementima, ova referenca je isto što i objekat document, pa tako i nememo puno potrebe za njom.
firstChild
firstElementChild
lastChild
lastElementChild
Svojstva firstChild i lastChild referenciraju prvi, odnosno poslednji podobjekat, bez obzira da li je u pitanju Node ili Element objekat. Na sličan način funkcionišu svojstva firstElementChild i lastElementChild, s tim što referenciraju prvi odnosno poslednji podelement.
<div>
Neki tekst... // firstChild
<p>...</p> // firstElementChild
<p>...</p>
Neki tekst...
<p>...</p> // lastElementChild
Neki tekst... // lastChild
</div>
Ako podobjekat (podelemenat) ne postoji, ova svojstva imaju vrednost null. Ako postoji samo jedan podobjekat (podelemenat), svojstva koja referenciraju prvi, pokazuju na isti objekat kao i svojstva koja referenciraju poslednji podobjekat.
<div>
Neki tekst... // firstChild
<p>...</p> // firstElementChild, lastElementChild, lastChild
</div>
nextSibling
nextElementSibling
previousSibling
previousElementSibling
Jednom kada se "dohvatimo" objekta, možemo se kretati napred ili nazad korišćenjem svojstava nextSibling (nextElementSibling) i previousSibling (previousElementSibling). Objekat koji je prvi na svom nivou ima vrednost null svojstva koje pokazuje na prethodni objekat. Isto tako, svojstva koja pokazuju na sledeći objekat u poslednjem objektu imaju vrednost null.
<div>
Neki tekst...
<p>...</p>
<p>...</p> // previousElementSibling
Neki tekst... // previousSibling
<p>...</p>
Neki tekst... // nextSibling
<p>...</p> // nextElementSibling
Neki tekst...
<p>...</p>
</div>
childNodes
children
Ako koristimo ova svojstva koja referenciraju prethodni/sledeći objekat, za prolazak kroz listu, koristićemo uslovni ciklus. Ako želimo da koristimo brojački ciklus, potrebno je da imamo sve objekte u nizu, ili bar strukturi koja enumeriše objekte. Drugim rečima, treba nam način da svakom objektu pristupimo preko rednog broja.
Svojstvo childNodes enumeriše sve objekte, a children samo elemente. Prvi podobjekat ima indeks 0. Ova struktura nije objekat niza (Array) - ne možemo koristiti metode koji se normalno koriste u nizu. U pitanju je HTML kolekcija, a nama je bitno što i ona ima svojstvo length (broj elemenata) i što svakom objektu pristupamo preko indeksa, kao da je u pitanju član niza.
Pošto slika govori više od reči, evo grafičkog prikaza svega o čemu smo pisali.
Primer
U prvom okviru vidimo način prolaska kroz listu elemenata korišćenjem uslovnog ciklusa. Ovo je klasičan način za prolazak kroz članove vezane liste. Na kraju ciklusa referenca x se preusmerava na elemenat koji dolazi posle elementa na koji x pokazuje u tom trenutku (x.nextElementSibling). Elementi kroz koje prolazimo se nalaze unutar objekta obj, koji predstavlja HTML element sa ID-em "element".
var obj = document.getElementById("element");
var x = obj.firstElementChild;
while (x) {
// ... obrada elementa x
x = x.nextElementSibling;
}
U drugom okviru vidimo drugi način prolaska kroz listu elemenata koji su enumerisani preko svojstva children. U ovom slučaju kroz elemente prolazimo brojačkim ciklusom. Svakom elementu pristupamo kao članu niza niz, a prvi elemenat ima indeks 0.
var obj = document.getElementById("element");
var niz = obj.children;
for (var i=0; i<niz.length; i++) {
// ... obrada elementa niz[i]
}
Pogledajte kako bi to izgledalo u interaktivnom primeru.
Drugi primer demonstrira rekurzivni prolazak kroz sve elemente zadatog objekta.