Poznajemy Tree Walkery w JavaScript, czyli coś, czego jeszcze nie robiliśmy, a bardzo one upraszczają zaawansowaną kontrolę nad DOM. Do dzieła.
Ok, to nasz markup:
<ul id="list">
My list:
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
A to nasz TreeWalker:
const treeWalker = document.createTreeWalker(
document.querySelector("#list"),
NodeFilter.SHOW_TEXT,
);
while (treeWalker.nextNode()) {
const node = treeWalker.currentNode;
node.data = node.data.toUpperCase();
}
Podnosi wszystkie text nodes (także te wewnątrz li) do wielkiej litery. A gdybyśmy tak chcieli tylko textNodes poza li podnieść do wielkiej litery?
const treeWalker = document.createTreeWalker(
document.querySelector("#list"),
NodeFilter.SHOW_TEXT,
);
while (treeWalker.nextNode()) {
const node = treeWalker.currentNode;
if(node.parentElement.matches("ul#list"))
node.data = node.data.toUpperCase();
}
Możemy nawet zmodyfikować markup, aby zobaczyć, czy działa:
<ul id="list">
My list:
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
End of my list...
</ul>
Ok, napiszmy sobie jakieś komentarze w HTMLu:
<ul id="list">
<!-- comment one -->
My list:
<li>List item 1 <!-- comment two --> </li>
<li>List item 2</li>
<li>List item 3</li>
End of my list...
<!-- comment three -->
</ul>
I prosty skrypt, który nam odczyta te komentarze:
const treeWalker = document.createTreeWalker(
document.querySelector("#list"),
NodeFilter.SHOW_COMMENT,
);
while (treeWalker.nextNode()) {
const node = treeWalker.currentNode;
console.log(node.data);
}
Ok, zmieniamy nieco markup:
<ul id="list">
<!-- comment one -->
My list:
<li class="show">show me</li>
<li class="skip">skip</li>
<li class="reject">reject</li>
<li class="show">show me, but you wont...</li>
End of my list...
<!-- comment three -->
</ul>
Na początek wyświetlimy sobie wszystkie elementy:
const treeWalker = document.createTreeWalker(
document.querySelector("#list"),
NodeFilter.SHOW_ELEMENT,
);
while (treeWalker.nextNode()) {
const node = treeWalker.currentNode;
console.log(node.textContent);
}
Ok, a teraz wykorzystamy trzeci, opcjonalny argument dla tree walkera:
const treeWalker = document.createTreeWalker(
document.querySelector("#list"),
NodeFilter.SHOW_ELEMENT,
(node) => {
if(node.classList.contains("show"))
return NodeFilter.FILTER_ACCEPT;
else if(node.classList.contains("skip"))
return NodeFilter.FILTER_SKIP;
else if(node.classList.contains("reject"))
return NodeFilter.FILTER_REJECT;
}
);
while (treeWalker.nextNode()) {
const node = treeWalker.currentNode;
console.log(node.textContent);
}
Pokazuje show me, oraz show me, but you wont. Cóż, reject do czego innego służy:
<ul id="list">
<li class="show"><span class="show">show me</span></li>
<li class="skip">skip</li>
<li class="reject">reject<span class="show">show me, but you wont</span></li>
<li class="show">show me 2</li>
</ul>
Reject odrzuca subtree danego elementu, ale iterator idzie dalej. Teraz mamy show me i show me 2. To warto sobie uświadomić – TreeWalker chodzi po strukturze drzewa.
Jeżeli chcemy prosty iterator, który chodzi po tablicy i nie patrzy jak zagnieżdżone są elementy, to mamy NodeIterator (document.createNodeIterator)…