Как отфильтровать и просмотреть дерево DOM с помощью JavaScript
Знаете ли вы, что есть JavaScript API, единственной миссией которого является отфильтровывать и перебирать узлы мы хотим от дерева DOM? На самом деле, не один, а два таких API: NodeIterator
а также TreeWalker
. Они очень похожи друг на друга, с некоторыми полезными отличиями. Оба могут вернуть список узлов которые присутствуют в данном корневом узле при соблюдении любые предопределенные и / или пользовательские правила фильтрации применяется к ним.
Предопределенные фильтры, доступные в API, могут помочь нам нацелены на различные виды узлов такие как текстовые узлы или узлы элементов, а также пользовательские фильтры (добавленные нами) могут далее отфильтровать связку, например, путем поиска узлов с конкретным содержимым. Возвращенный список узлов итерируемый, то есть они могут быть перебрал, и мы можем работать со всеми отдельными узлами в списке.
Как использовать NodeIterator
API
NodeIterator
объект может быть создан с использованием createNodeIterator ()
метод документ
интерфейс. Этот метод принимает три аргумента. Первый требуется; Это”с корневой узел который содержит все узлы, которые мы хотим отфильтровать.
Второй и третий аргументы необязательный. Они предопределенные и пользовательские фильтры, соответственно. Предопределенные фильтры доступны для использования в качестве константы NodeFilter
объект.
Например, если NodeFilter.SHOW_TEXT
константа добавляется как второй параметр, он будет возвращать итератор для список всех текстовых узлов под корневым узлом. NodeFilter.SHOW_ELEMENT
вернусь только узлы элемента. Смотрите полный список все доступные константы.
Третий аргумент (пользовательский фильтр) является функция, которая реализует фильтр.
Вот пример кода:
Документ заглавие
это обертка страницытекст какая-то ссылкаПривет
Как твои дела?
Предполагая, что мы хотим извлечь содержимое всех текстовых узлов, которые находятся внутри #wrapper
ДИВ, это то, как мы делаем это, используя NodeIterator
:
var div = document.querySelector ('# wrapper'); var nodeIterator = document.createNodeIterator (div, NodeFilter.SHOW_TEXT); while (nodeIterator.nextNode ()) console.log (nodeIterator.referenceNode.nodeValue.trim ()); / * консольный вывод [Log] это обёртка страницы [Log] Hello [Log] [Log] Как дела? [Журнал] */
NextNode ()
метод NodeIterator
API возвращает следующий узел в списке повторяемых текстовых узлов. Когда мы используем его в в то время как
Цикл для доступа к каждому узлу в списке, мы записываем обрезанное содержимое каждого текстового узла в консоль. referenceNode
собственностью NodeIterator
возвращает узел, к которому в данный момент присоединен итератор.
Как вы можете видеть в выводе, есть некоторые текстовые узлы с пустыми пробелами для их содержимого. Мы можем избегать показа этого пустого содержимого с помощью пользовательского фильтра:
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 ()); / * консольный вывод [Log] это обертка страницы [Log] Привет [Log] Как дела? * /
Пользовательская функция фильтра возвращает константу NodeFilter.FILTER_ACCEPT
если текстовый узел не пуст, что приводит к включению этого узла в список узлов, по которым будет повторяться итератор. Наоборот, NodeFilter.FILTER_REJECT
константа возвращается для того, чтобы исключить пустые текстовые узлы из итеративного списка узлов.
Как использовать TreeWalker
API
Как я уже говорил, NodeIterator
а также TreeWalker
API являются похожи друг на друга.
TreeWalker
может быть создан с помощью createTreeWalker ()
метод документ
интерфейс. Этот метод, так же, как createNodeFilter ()
, принимает три аргумента: корневой узел, предопределенный фильтр и пользовательский фильтр.
Если мы использовать TreeWalker
API вместо NodeIterator
предыдущий фрагмент кода выглядит следующим образом:
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] это обёртка страницы [Log] Привет [Log] Как дела? * /
Вместо referenceNode
, сиггепЬЫойе
собственность TreeWalker
API используется для получить доступ к узлу, к которому в данный момент подключен итератор. В добавок к NextNode ()
метод, TreeWalker
есть другие полезные методы. previousNode ()
метод (также присутствует в NodeIterator
) возвращает предыдущий узел узла, к которому в данный момент привязан итератор.
Подобная функциональность выполняется ParentNode ()
, Первый ребенок()
, последний ребенок()
, PreviousSibling ()
, а также NextSibling ()
методы. Эти методы доступно только в TreeWalker
API.
Вот пример кода, который выводит последнего потомка узла итератор привязан к:
var div = document.querySelector ('# wrapper'); var treeWalker = document.createTreeWalker (div, NodeFilter.SHOW_ELEMENT); console.log (treeWalker.lastChild ()); / * вывод [Журнал]Как твои дела?
* /
Какой API выбрать
Выбрать NodeIterator
API, когда вы нужен простой итератор фильтровать и перебирать выбранные узлы. И выберите TreeWalker
API, когда вы необходимо получить доступ к семейству отфильтрованных узлов, такие как их ближайшие братья и сестры.