Mozilla Hacks: Przechodzenie po drzewie DOM w Firefoksie 3.5

W ramach serii tłumaczeń artykułów z bloga Mozilla Hacks, przedstawiam dzisiaj tłumaczenie artykułu DOM Traversal in Firefox 3.5 autorstwa Johna Resiga (znanego m. in. jako twórca biblioteki jQuery). Oryginalny artykuł i jego tłumaczenie dostępne są na warunkach licencji Creative Commons Attribution 3.0 USA.

Przechodzenie po drzewie DOM w Firefoksie 3.5

Firefox 3.5 obsługuje dwie nowe specyfikacje W3C dotyczące przechodzenia po drzewie DOM. Pierwsza z nich – Element Traversal API – ułatwia przechodzenie pomiędzy kolejnymi elementami, a druga – interfejs NodeIterator – sprawia, że odnajdywanie węzłów wszystkich typów staje się prostsze.

Element Traversal API

Zadaniem Element Traversal API (API przechodzenia po elementach) jest ułatwienie przechodzenia po elementach w drzewie DOM z pominięciem pośrednich węzłów tekstowych, węzłów komentarzy itp. Rozwiązuje to istniejący od dawna problem irytujący programistów; w szczególności problematyczne były przypadki, w których document.documentElement.firstChild miało różną wartość w zależności od występowania białych spacji w dokumencie.

Element Traversal API wprowadza kilka nowych własności węzłów DOM, znacznie ułatwiających przechodzenie drzewa.

Poniżej zestawienie istniejących dotychczas własności DOM i ich nowych odpowiedników:

Cel Wszystkie węzły DOM Tylko elementy DOM
Pierwszy .firstChild .firstElementChild
Ostatni .lastChild .lastElementChild
Poprzedni .previousSibling .previousElementSibling
Następny .nextSibling .nextElementSibling
Długość .childNodes.length .childElementCount

Własności te są dość prostym rozszerzeniem specyfikacji DOM (szczerze mówiąc, powinny się w niej znajdować od początku).

Jednej własności jednakże brakuje: .childElements (jako odpowiednika .childNodes). Własność ta (zawierająca dynamiczną kolekcję typu NodeSet elementów potomnych danego elementu DOM) znajdowała się w poprzednich iteracjach tej specyfikacji, ale w międzyczasie została z niej usunięta.

Ale nie wszystko stracone. Obecnie Internet Explorer, Opera i Safari obsługują własność .children, oferującą nadzbiór funkcjonalności, która miała być udostępniana przez .childElements. Kiedy obsługa Element Traversal API została włączona do Firefoksa 3.5, zaimplementowana wraz z nią została także kolekcja .children. Oznacza to, że obecnie każda z głównych przeglądarek obsługuje tę własność (wyprzedza ona pod tym względem właściwą specyfikację Element Traversal).

Oto kilka przykładów wykorzystania Element Traversal API (i kolekcji .children):

Wyświetl następny element po kliknięciu:

someElement.addEventListener("click", function(){
    this.nextSiblingElement.style.display = "block";
}, false);

Ustaw klasę dla wszystkich elementów bezpośrednio podrzędnych:

for ( var i = 0; i < someElement.children.length; i++ ) {
    someElement.children[ i ].className = "active";
}

NodeIterator API

NodeIterator to dość stare API, które nie było dotąd szeroko stosowane, a obecnie zostało zaimplementowane w Firefoksie 3.5. NodeIterator API ma na celu ułatwienie przechodzenie po wszystkich węzłach dokumentu DOM (w tym węzłów tekstowych, komentarzy itd.).

Samo API jest dość zawiłe (zawiera sporo funkcji, które nie są specjalnie istotne dla większości programistów), ale w prostych zastosowaniach jest dość łatwe w użyciu.

Zasada działania jest następująca: tworzymy instancję NodeIterator (za pomocą document.createNodeIterator) i przekazujemy jej zbiór filtrów. NodeIterator potrafi zwrócić wszystkie węzły w dokumencie (czy w kontekście danego węzła), dlatego zwykle chcemy odfiltrować wyniki, by dostać tylko pożądane węzły. Oto prosty przykład:

Utwórzmy instancję NodeIterator, by przeiterować po wszystkich węzłach komentarzy w dokumencie.

var nodeIterator = document.createNodeIterator(
    document,
    NodeFilter.SHOW_COMMENT,
    null,
    false
);

var node;

while ( (node = nodeIterator.nextNode()) ) {
    node.parentNode.removeChild( node );
}

Po utworzeniu NodeIterator jest dwukierunkowy (można przechodzić w dowolnym kierunku, przy pomocy własności previousNode i nextNode).

Prawdopodobnie najsensowniejszym zastosowaniem tego API jest przechodzenie po często używanych (ale w inny sposób trudnych do przejścia) węzłach, takich jak komentarze i węzły tekstowe. Jako że istnieje już kilka innych API do przechodzenia po elementach DOM (jak np. getElementsByTagName), omówione tu API jest kolejną przydatną alternatywą dla innych sposobów na przechodzenie węzłów dokumentu.

W uzupełnieniu powyższego artykułu Johna – dwa zdania ode mnie na ten temat. W swoim blogu autor powyższego artykułu jest bardziej krytyczny co do NodeIteratora. Zgadzam się z nim tutaj w pełni – osobiście mam wrażenie, że gdyby nie test ACID 3, którego NodeIterator jest częścią, nie zobaczylibyśmy implementacji tego API w Gecko. Omówione w pierwszej części artykułu Element Traversal API jest natomiast zdecydowanie bardziej przydatne w codziennej pracy web developera.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

MDN

Better JavaScript docs for a better Web on MDN

Archiwum

%d bloggers like this: