Jak filtrować i przemieszczać drzewo DOM za pomocą JavaScript
Czy wiesz, że istnieje API JavaScript, którego jedyną misją jest odfiltrować i iterować przez węzły chcemy z drzewa DOM? W rzeczywistości nie jeden, ale są dwa takie API: NodeIterator
i TreeWalker
. Są do siebie bardzo podobne, z pewnymi użytecznymi różnicami. Obie mogą zwróć listę węzłów które są obecne pod danym węzłem głównym, podczas gdy są zgodne wszelkie predefiniowane i / lub niestandardowe reguły filtrowania zastosowane do nich.
Wstępnie zdefiniowane filtry dostępne w interfejsach API mogą nam pomóc kierować na różne rodzaje węzłów takie jak węzły tekstowe lub węzły elementów i niestandardowe filtry (dodane przez nas) dalej filtruj pęczek, na przykład szukając węzłów o określonej zawartości. Zwrócona lista węzłów to iterowalny, tj. mogą być zapętlony, i możemy pracować ze wszystkimi pojedynczymi węzłami na liście.
Jak korzystać z NodeIterator
API
ZA NodeIterator
obiekt można utworzyć za pomocą createNodeIterator ()
metoda dokument
berło. Ta metoda bierze trzy argumenty. Pierwszy jest wymagany; to”s Węzeł główny który zawiera wszystkie węzły, które chcemy odfiltrować.
Drugi i trzeci argument są opcjonalny. Oni są predefiniowane i niestandardowe filtry, odpowiednio. Wstępnie zdefiniowane filtry są dostępne do użycia jako stałe NodeFilter
obiekt.
Na przykład, jeśli NodeFilter.SHOW_TEXT
stała jest dodawana jako drugi parametr zwróci iterator dla a lista wszystkich węzłów tekstowych pod węzłem głównym. NodeFilter.SHOW_ELEMENT
wróci tylko węzły elementu. Zobacz pełną listę wszystkie dostępne stałe.
Trzeci argument (filtr niestandardowy) to a funkcja implementująca filtr.
Oto jest przykładowy fragment kodu:
Dokument tytuł
to jest opakowanie stronytekst jakiś linkdzień dobry
Jak się masz?
Zakładając, że chcemy wyodrębnij zawartość wszystkich węzłów tekstowych znajdujących się wewnątrz #obwoluta
div, tak się do tego zabieramy NodeIterator
:
var div = document.querySelector ('# wrapper'); var nodeIterator = document.createNodeIterator (div, NodeFilter.SHOW_TEXT); while (nodeIterator.nextNode ()) console.log (nodeIterator.referenceNode.nodeValue.trim ()); / * wyjście konsoli [Log] to opakowanie strony [Log] Hello [Log] [Log] Jak się masz? [Log] * /
The nextNode ()
metoda NodeIterator
API zwraca następny węzeł na liście iterowalnych węzłów tekstowych. Kiedy używamy go w podczas
aby uzyskać dostęp do każdego węzła na liście, zapisujemy przyciętą zawartość każdego węzła tekstowego do konsoli. The referenceNode
własność NodeIterator
zwraca węzeł, do którego dołączony jest iterator.
Jak widać na wyjściu, istnieją pewne węzły tekstowe z pustymi miejscami na ich zawartość. Możemy unikać pokazywania tych pustych treści przy użyciu niestandardowego filtru:
var div = document.querySelector ('# wrapper'); var nodeIterator = document.createNodeIterator (div, NodeFilter.SHOW_TEXT, function (node) return (node.nodeValue.trim ()! == "")? NodeFilter.FILTER_ACCEPT: NodeFilter.FILTER_REJECT;); while (nodeIterator.nextNode ()) console.log (nodeIterator.referenceNode.nodeValue.trim ()); / * wyjście konsoli [Log] to opakowanie strony [Log] Hello [Log] Jak się masz? * /
Funkcja filtra niestandardowego zwraca stałą NodeFilter.FILTER_ACCEPT
jeśli węzeł tekstowy nie jest pusty, co prowadzi do włączenia tego węzła na listę węzłów, nad którymi iterator będzie iterował. W przeciwieństwie do NodeFilter.FILTER_REJECT
stała jest zwracana w celu wykluczyć puste węzły tekstowe z iterowalnej listy węzłów.
Jak korzystać z TreeWalker
API
Jak już wspomniałem wcześniej NodeIterator
i TreeWalker
API są podobne do siebie.
TreeWalker
można utworzyć za pomocą createTreeWalker ()
metoda dokument
berło. Ta metoda, podobnie jak createNodeFilter ()
, bierze trzy argumenty: węzeł główny, predefiniowany filtr i filtr niestandardowy.
Jeśli my Użyj TreeWalker
API zamiast NodeIterator
poprzedni fragment kodu wygląda następująco:
var div = document.querySelector ('# wrapper'); var treeWalker = document.createTreeWalker (div, NodeFilter.SHOW_TEXT, function (node) return (node.nodeValue.trim ()! == "")? NodeFilter.FILTER_ACCEPT: NodeFilter.FILTER_REJECT;); while (treeWalker.nextNode ()) console.log (treeWalker.currentNode.nodeValue.trim ()); / * output [Log] to opakowanie strony [Log] Hello [Log] Jak się masz? * /
Zamiast referenceNode
, currentNode
własność TreeWalker
API jest przyzwyczajony uzyskaj dostęp do węzła, do którego dołączony jest iterator. Dodatkowo nextNode ()
metoda, Treewalker
ma inne przydatne metody. The previousNode ()
metoda (także obecna w NodeIterator
) zwraca poprzedni węzeł węzła, do którego jest obecnie zakotwiczony iterator.
Podobną funkcjonalność wykonuje parentNode ()
, pierworodny()
, ostatnie dziecko()
, previousSibling ()
, i nextSibling ()
metody. Te metody są dostępne tylko w TreeWalker
API.
Oto przykład kodu wyświetla ostatnie dziecko węzła iterator jest zakotwiczony w:
var div = document.querySelector ('# wrapper'); var treeWalker = document.createTreeWalker (div, NodeFilter.SHOW_ELEMENT); console.log (treeWalker.lastChild ()); / * output [Log]Jak się masz?
* /
Który API wybrać
Wybierz NodeIterator
API, kiedy ty potrzebujesz tylko prostego iteratora filtrować i przechodzić przez wybrane węzły. I wybierz TreeWalker
API, kiedy ty trzeba uzyskać dostęp do rodziny filtrowanych węzłów, takich jak ich bezpośrednie rodzeństwo.