TGViewer
Дивовижний світ веброзробки Дивовижний світ веброзробки @babichdev · 2.91K subscribers
Post #239 2.37K
#dom_api
Не буду стверджувати, що обхід DOM-дерева є повсякденною рутиною, але іноді така потреба постає, і тоді перед нами постає вибір: або ми це робимо рекурсивно і вручну, або нормально. Питання лише в тому, що про нормальний спосіб мало хто знає. От я знаю про нього вже кілька років, а на практиці довелося використати буквально днями.

Мова йтиме про TreeWalker. Як я вже казав, про його існування я знав давно, але прикладних задач для нього не мав. Аж тут сталося цікаве співпадіння: по-перше, Дмитро Тарасенко розповідав про свою маленьку бібліотечку для скрапінгу на React+ Fwdays'25, чим нагадав мені про існування TreeWalker взагалі, і, по-друге, днями я брав участь в досить цікавому лайвкодингу, де мені довелося в прямому етері, так би мовити, вперше з цим API попрацювати. Тож в двох словах розповім про нього.

Якщо коротко, то TreeWalker дозволяє послідовно обходити дерево вузлів DOM. Але є кілька дуже важливих нюансів. Перше, можна фільтрувати тип вузлів за власними правилами. Друге — він не обмежує нас в напрямку руху обходу, на відміну від рекурсії.

Так-так, він завжди памʼятає поточну ноду і дозволяє рухатися як вверх-вниз, так і по сусідах, а не лише вперед і вниз.

Це робить його дуже гнучким інструментом для швидкого обходу дерева, бо з ним можна не лише мандрувати в будь-якому напрямку, а зупинити обхід у будь-який момент та потім, згодом, відновити його з того ж місця.

Виглядає ініціалізація приблизно так:
const walker = document.createTreeWalker(
// корінь обходу
document.body,
// тип вузлів, які враховуємо
NodeFilter.SHOW_ELEMENT,
// кастомний фільтр
{
acceptNode(node) {
return node.tagName === 'P'
? NodeFilter.FILTER_ACCEPT
: NodeFilter.FILTER_SKIP;
}
}
);


і потім перебираємо як нам до вподоби:
let node = walker.currentNode;

while (node) {
console.log(node.tagName);
node = walker.nextNode();
}


TreeWalker не є альтернативою NodeIterator, а радше його "прокачаною" версією. NodeIterator також послідовно рухається деревом, але строго вперед або назад, більше нагадуючи ручний рекурсивний підхід, але з можливістю "перемотки".

З вас вподобайка і поширення, навіть якщо досі ні чорта не зрозуміло.

Найчастіше TreeWalker використовується тоді, коли потрібний саме обхід дерева, а не просто querySelectorAll. Наприклад, коли нам потрібно знайти фрагменти дерева, що відповідає певній структурі, чи елемент за певними правилами, які не можна описати селектором. І так, на відміну від querySelector*, він дозволяє обходити саме вузли, не лише елементи.

Звичайно ж, без підводних каменів нікуди. По-перше, TreeWalker не бачить Shadow DOM. Ну, на те він і Shadow, звичайно.

По-друге, фільтр acceptNode викликається для кожного вузла, тому при великому DOM варто уникати зайвих перевірок.

І, по-третє, TreeWalker працює з живим DOM, тому, певно, варто уникати операцій з деревом під час обходу, інакше він може несподівано затягнутись.

TreeWalker — це маленький, але дуже потужний API. Він дозволяє пройтись DOM не "згори донизу", а саме так, як тобі зручно, дозволяючи самотужки задавати правила, перестрибувати від сусідів до сусідів, від батьківських вузлів до дочірніх і усе це — з кнопками "play", "pause", "rewind" і "forward" прямо з коробки. Така собі міжпросторова рекурсія з подорожами в часі (так, я полюбляю безглузді метафори).

Я навіть не буду питати, чи ви вже використовували його в проді, а якщо використовували — отримайте від мене щиру заздрість, що працюєте з такими цікавими задачами )

Що почитати:
📖 MDN: TreeWalker
📖 MDN: NodeIterator

Що почитати душнілам:
📖 W3C: Document Object Traversal
📖 WHATWG: TreeWalker

P.S. Товариство, детектори дронів самі себе не куплять, запрошую закинути пару гривень на збір.
  • 🔥 66
  • ❤ 24
  • 👍 12
  • 🤔 1
More from @babichdev
  1. Sep 30, 2026Товариство, запрошую вас цієї суботи, 3 жовтня, на Fwdays Tech Summit — онлайн конференцію…
  2. Sep 28, 2026#збір_на_авто_для_21 Товариство, почнімо тиждень з доброго діла. Я би дуже хотів, аби ми ц…
  3. Sep 27, 2026Знайшов своє старезне резюме. Аж пустив скупу сльозу за тими часами, коли навіть з таким м…
  4. Sep 25, 2026Днями на редіті побачив допис, в якому автор питав, чому його лічильник часу на сторінці з…
  5. Sep 23, 2026Який ШІ найкращий для навчання? Відповідь проста — той, з яким ви чогось навчились. ШІ це…
  6. Sep 18, 2026Оце я, канєшна, провтикав. Конфа завтра, 19 вересня. Ще встигаєте взяти квиточок.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →