Как отфильтровать и просмотреть дерево DOM с помощью JavaScript
Знаете ли вы, что есть JavaScript API, единственная миссия которого состоит в том, чтобы отфильтровывать и перебирать нужные нам узлы из дерева DOM? На самом деле не один, а два таких API: NodeIterator а также TreeWalker, Они очень похожи друг на друга, с некоторыми полезными отличиями. Оба могут возвращать список узлов, которые присутствуют в данном корневом узле, при этом соблюдая любые предопределенные и / или настраиваемые правила фильтрации, применяемые к ним.
Предопределенные фильтры, доступные в API, могут помочь нам нацеливаться на различные виды узлов, такие как текстовые узлы или узлы элементов, а пользовательские фильтры (добавленные нами) могут дополнительно фильтровать группу, например, путем поиска узлов с конкретным содержимым. Возвращенный список узлов является итеративным, то есть он может быть зациклен, и мы можем работать со всеми отдельными узлами в списке.
Читайте также: Понимание объектной модели документа (DOM) в деталях
Программы для Windows, мобильные приложения, игры - ВСЁ БЕСПЛАТНО, в нашем закрытом телеграмм канале - Подписывайтесь:)
Как использовать API NodeIterator
Объект NodeIterator может быть создан с использованием createNodeIterator () метод интерфейса документа. Этот метод принимает три аргумента. Первый требуется; это корневой узел, который содержит все узлы, которые мы хотим отфильтровать.
Второй и третий аргументы являются необязательными. Это предопределенные и пользовательские фильтры соответственно. Предопределенные фильтры доступны для использования в качестве констант объекта NodeFilter.
Например, если константа NodeFilter.SHOW_TEXT добавлена в качестве второго параметра, она вернет итератор для списка всех текстовых узлов под корневым узлом. NodeFilter.SHOW_ELEMENT будет возвращать только узлы элемента. Смотрите полный список все доступные константы,
Третий аргумент (пользовательский фильтр) — это функция, которая реализует фильтр.
Вот пример кода:
заглавие
это обертка страницы
Привет</p>
<p>Как ты?</p>
</div>
<span>текст</span>
<a href="https://www.hongkiat.com/#">какая-то ссылка</a>
<footer>авторские права</footer>
Предполагая, что мы хотим извлечь содержимое всех текстовых узлов, находящихся внутри #wrapper div, мы так и поступаем, используя NodeIterator:
var div = document.querySelector (‘# wrapper’);
var nodeIterator = document.createNodeIterator (
ДИВ,
NodeFilter.SHOW_TEXT
);
while (nodeIterator.nextNode ()) {
console.log (nodeIterator.referenceNode.nodeValue.trim ());
}
/ * консольный вывод
[Log] это обертка страницы
[Log] Привет
[Log]
[Log] Как ты?
[Log]
* /
NextNode () Метод API NodeIterator возвращает следующий узел в списке повторяемых текстовых узлов. Когда мы используем его в цикле while для доступа к каждому узлу в списке, мы записываем обрезанное содержимое каждого текстового узла в консоль. referenceNode Свойство NodeIterator возвращает узел, к которому в данный момент присоединен итератор.
Как вы можете видеть в выводе, есть некоторые текстовые узлы с пустыми пробелами для их содержимого. Мы можем избежать показа этого пустого содержимого, используя специальный фильтр:
var div = document.querySelector (‘# wrapper’);
var nodeIterator = document.createNodeIterator (
ДИВ,
NodeFilter.SHOW_TEXT,
функция (узел) {
return (node.nodeValue.trim ()! == «»)?
NodeFilter.FILTER_ACCEPT: NodeFilter.FILTER_REJECT;
}
);
while (nodeIterator.nextNode ()) {
console.log (nodeIterator.referenceNode.nodeValue.trim ());
}
/ * консольный вывод
[Log] это обертка страницы
[Log] Привет
[Log] Как ты?
* /
Пользовательская функция фильтра возвращает константу NodeFilter.FILTER_ACCEPT, если текстовый узел не пуст, что приводит к включению этого узла в список узлов, по которым будет перебираться итератор. Напротив, константа NodeFilter.FILTER_REJECT возвращается, чтобы исключить пустые текстовые узлы из итерируемого списка узлов.
Как использовать TreeWalker API
Как я упоминал ранее, API-интерфейсы NodeIterator и TreeWalker похожи друг на друга.
TreeWalker может быть создан с помощью createTreeWalker () метод интерфейса документа. Этот метод, как и createNodeFilter (), принимает три аргумента: корневой узел, предопределенный фильтр и пользовательский фильтр.
Если мы будем использовать TreeWalker API вместо NodeIterator, предыдущий фрагмент кода будет выглядеть следующим образом:
var div = document.querySelector (‘# wrapper’);
var treeWalker = document.createTreeWalker (
ДИВ,
NodeFilter.SHOW_TEXT,
функция (узел) {
return (node.nodeValue.trim ()! == «»)?
NodeFilter.FILTER_ACCEPT: NodeFilter.FILTER_REJECT;
}
);
while (treeWalker.nextNode ()) {
console.log (treeWalker.currentNode.nodeValue.trim ());
}
/* вывод
[Log] это обертка страницы
[Log] Привет
[Log] Как ты?
* /
Вместо referenceNode, сиггепЬЫойе свойство API TreeWalker используется для доступа к узлу, к которому в данный момент присоединен итератор. В дополнение к методу nextNode (), в Treewalker есть и другие полезные методы. previousNode () метод (также присутствует в NodeIterator) возвращает предыдущий узел узла, к которому в данный момент привязан итератор.
Подобная функциональность выполняется ParentNode (), Первый ребенок(), последний ребенок(), PreviousSibling (), а также NextSibling () методы. Эти методы доступны только в TreeWalker API.
Вот пример кода, который выводит последнего потомка узла, к которому привязан итератор:
var div = document.querySelector (‘# wrapper’);
var treeWalker = document.createTreeWalker (
ДИВ,
NodeFilter.SHOW_ELEMENT
);
console.log (treeWalker.lastChild ());
/* вывод
[Log] Как ты?
- /
Какой API выбрать
Выберите NodeIterator API, когда вам нужен простой итератор для фильтрации и циклического прохождения по выбранным узлам. И выберите API TreeWalker, когда вам нужно получить доступ к семейству отфильтрованных узлов, таких как их непосредственные братья и сестры.
Читайте также: 15 методов JavaScript для управления DOM для веб-разработчиков
Программы для Windows, мобильные приложения, игры - ВСЁ БЕСПЛАТНО, в нашем закрытом телеграмм канале - Подписывайтесь:)