Обход дерева DOM
Table Of Content
Сегодня я поигрался с несколькими вещами и решил поделиться очень простой функцией обхода дерева DOM. Как вы, наверное, уже знаете, узлы DOM имеют разные типы, и для полного списка можно обратиться к странице w3schools.
Мой случай использования был извлечение комментариев со страницы, поэтому я рассмотрю только этот конкретный случай, но код настраивается и для других типов узлов.
Есть 2 варианта поиска контента в дереве DOM:
- Парсинг HTML для комментариев - не то, чем хочется заниматься в свободное время, особенно без какой-либо существующей библиотеки. Есть еще один случай, когда вы можете захотеть избежать этого, и это когда вы хотите изменить соответствующие элементы на странице (через некоторое расширение браузера или скрипт), потому что вам нужно будет сопоставить фрагменты строки с реальным элементом DOM, и это не звучит как весело.
Ниже приведен пример обхода дерева DOM с использованием рекурсии:
const COMMENT_NODE_TYPE = 8
const TYPE_TO_LOG_OUT = COMMENT_NODE_TYPE
function traverse(node) {
if (node.nodeType === TYPE_TO_LOG_OUT) {
console.log(node.nodeValue)
}
if (node.hasChildNodes()) {
Array.prototype.forEach.call(node.childNodes, (childNode) => {
traverse(childNode)
})
}
}
// передайте начальный (корневой) узел - может быть любым узлом DOM
// в примере используется документ, потому что это родительский элемент для элементов head и body, поэтому код соберет все внутренние комментарии разметки
traverse(document)
Этот код использует константу для типа узла комментария (число 8). Функция traverse
- это рекурсивная функция, которая принимает корневой узел. Если тип узла равен узлу комментария, его значение выводится в консоль. Если у узла есть дочерние узлы, мы спускаемся по ним, вызывая функцию traverse
для каждого из них (процесс повторяется для дочернего узла). Выполнение распространяется через дочерние узлы и вниз по иерархии, пока больше нет дочерних узлов.
Вот и все, обходите эти узлы, как будто завтра не наступит!