Sposoby odnajdywania elementów w DOM
08 marca 2006
Wcześniej powiedziałem, że DOM można, a nawet powinno się, obrazować jako drzewo. DOM jako API udostępnia nam cały zestaw metod odnajdywania interesującego nas elementu w gałęziach tego drzewa.
Możemy wyszukać zestaw elementów i za pomocą paru dodatkowych sztuczek odnaleźć ten jedyny. Możemy także korzystać z relacji elementu aktywnego z jego rodzicami, dziećmi jak i rodzeństem - słownictwo bardzo rodzinne, ale dokładnie z tych nazw w języku angielskim korzystają nazwy tych metod.
Mała uwaga: nazwy metod piszemy stylem wielbłądzim, pozostawiając pierwszą literę małą.
Całkowitą podstawą jest getElementById. Po wywołaniu
document.getElementById("content")
otrzymamy element posiadający id="content", jeśli taki znajduje się na stronie. Warto przed przystąpieniem do operacji na uchwycie sprawdzić czy znajduje się on w dokumencie.
var handle = document.getElementById("content");if (handle) {…} else {return false;}
W innym przypadku, biorąc tylko pod uwagę interakcję użytkownik - strona, Internet Explorer wywali okienko z wielką złą czerwoną ikoną i mało zachęcającym komunikatem.
No dobrze, powiesz, ale przecież nie będę pisał w każdym znaczniku jakiegoś id, żeby potem móc operować na nim w JavaScripcie. Oczywiście, że nie - getElementById to wierzchołek góry lodowej. Dalej mamy getElementsByTagName. Metoda ta pobierze do tablicy wszystkie elementy znajdujące się w drzewku pod elementem z którego ją wywołaliśmy.
document.getElementsByTagName("p")
zwróci wszystkie akapity na stronie włożone do tablicy. Skorzystanie z
document.getElementById("content").getElementsByTagName("p")
przy założeniu, że w dokumencie mamy jakiś tag z id="content" pozwoli pobrać wszystkie akapity w nim zawarte jak i w jego potomkach. Ilustruje to graf:

Do tablicy możemy odwoływać się korzystając z numeru indeksu:
getElementsByTagName("p")[0]
Zwróci nam to pierwszy akapit (w tablicach indeks zaczyna się od 0). Jest to też sposób na pobranie uchwytu do elementu, który występuje tylko raz (jeśli wiemy to na pewno) w danej gałęzi, bo nie ma czegoś takiego jak
getElementByTagName("p")
Oczywiście mając tablicę możemy wykonać na niej operacje, najszybciej korzystając z pętli:
for (var i = 0; i < paragraphs.length; i++) { … instrukcje … }
W przykładzie i to zmienna licznika tablicy (zwiększająca się o jeden w cyklu, o czym mówi zapis i++), paragraphs jest na przykład zmienną przechowującą wynik naszego wcześniejszego getElementsByTagName("p"), a zapis .length odwołuje się do jej wielkości. Cała linijka znaczy tyle, że pętla będzie się wykonywać tyle razy ile mamy akapitów p w paragraphs.
Odwołanie do elementu w pętli jest podobne jak w poprzednim przykładzie, tylko zamiast podawać gotową liczbę, wstawiamy zmienną i:
paragraphs[i]
Aby pobrać wszystkie elementy z aktualnej gałęzi (w przypadku document będą to wszystkie elementy dokumentu) należy użyć znaku gwiazdki:
getElementsByTagName("*")
Teraz trochę o relacjach. Będąc w określonym miejscu w DOM możemy odnieść się do elementu powyżej nas - rodzica. Służy do tego parentNode.

Gdy jesteśmy zmuszeni odwołać się do wszystkich elementów poziom niżej danego węzła, używamy childNodes. Warto sprawdzić czy element posiada jakieś childNodes stosując warunek z hasChildNodes. Jeśli okaże się, że istnieje jest tylko jeden element, childNodes nadal zwraca tablicę, do której możemy odwołać się jak poprzednio - childNodes[0].

DOM udostępnia także łatwe metody na pobranie pierwszego - firstChild - i ostatniego - lastChild - elementu niżej w gałęzi.

Na koniec zostają metody i zwracające element po - nextSibling - i przed - previousSibling - elementem z którego je wywołujemy. W ten sposób można się łatwo przełączać między jednopoziomowymi węzłami, nawet jeśli mają pod sobą dalsze rozgałęzienia.

Korzystając z tych relacji jedynie dostajemy „uchwyt” za pomocą którego możemy modyfikować atrybuty aktualnego elementu. Samego elementu podmenić nie możemy - o metodach wstawiania, podmiany oraz usuwania elementów drzewa opowiem wkrótce. W końcu także dojdziemy do przykładów z życia wziętych, aby nie zanudzić się podręcznikowymi formułkami.


