Como filtrar e atravessar a árvore DOM com JavaScript
Você sabia que existe uma API JavaScript cuja única missão é filtrar e iterar pelos nós queremos de uma árvore DOM? Na verdade, não um, mas existem duas APIs desse tipo: NodeIterator
e TreeWalker
. Eles são muito parecidos uns com os outros, com algumas diferenças úteis. Ambos podem retornar uma lista de nós que estão presentes sob um determinado nó raiz enquanto cumprem quaisquer regras de filtro predefinidas e / ou personalizadas aplicado a eles.
Os filtros predefinidos disponíveis nas APIs podem nos ajudar segmentar diferentes tipos de nós como nós de texto ou nós de elementos, e filtros personalizados (adicionados por nós) podem filtrar ainda mais o grupo, por exemplo, procurando por nós com conteúdo específico. A lista retornada de nós é iterável, ou seja, eles podem ser circulou, e podemos trabalhar com todos os nós individuais da lista.
Como usar o NodeIterator
API
UMA NodeIterator
objeto pode ser criado usando o createNodeIterator ()
método do documento
interface. Este método leva três argumentos. O primeiro é obrigatório; isto”s o nó raiz que contém todos os nós que queremos filtrar.
O segundo e terceiro argumentos são opcional. Eles são o filtros predefinidos e personalizados, respectivamente. Os filtros predefinidos estão disponíveis para uso como constantes da NodeFilter
objeto.
Por exemplo, se o NodeFilter.SHOW_TEXT
constante é adicionada como o segundo parâmetro que irá retornar um iterador para um lista de todos os nós de texto sob o nó raiz. NodeFilter.SHOW_ELEMENT
retornará apenas os nós do elemento. Veja uma lista completa de todas as constantes disponíveis.
O terceiro argumento (o filtro personalizado) é um função que implementa o filtro.
Aqui está um exemplo de snippet de código:
Documento título
este é o wrapper da páginaTXT algum linkOlá
Como você está?
Assumindo que queremos extrair o conteúdo de todos os nós de texto que estão dentro do #embrulho
div, é assim que vamos fazer isso usando NodeIterator
:
var div = document.querySelector ('# wrapper'); var nodeIterator = document.createNodeIterator (div, NodeFilter.SHOW_TEXT); while (nodeIterator.nextNode ()) console.log (nodeIterator.referenceNode.nodeValue.trim ()); / * saída do console [Log] este é o wrapper da página [Log] Olá [Log] [Log] Como você está? [Registro] */
o nextNode ()
método do NodeIterator
API retorna o próximo nó na lista de nós de texto iteráveis. Quando nós usá-lo em um enquanto
loop para acessar cada nó na lista, registramos o conteúdo aparado de cada nó de texto no console. o referenceNode
propriedade de NodeIterator
retorna o nó ao qual o iterador está atualmente conectado.
Como você pode ver na saída, existem alguns nós de texto com apenas espaços vazios para o seu conteúdo. Podemos evite mostrar esses conteúdos vazios usando um filtro personalizado:
var div = document.querySelector ('# wrapper'); var nodeIterator = document.createNodeIterator (div, NodeFilter.SHOW_TEXT, função (nó) return (node.nodeValue.trim ()! == "")? NodeFilter.FILTER_ACCEPT: NodeFilter.FILTER_REJECT;); while (nodeIterator.nextNode ()) console.log (nodeIterator.referenceNode.nodeValue.trim ()); / * saída do console [Log] este é o wrapper da página [Log] Olá [Log] Como você está? * /
A função de filtro personalizado retorna a constante NodeFilter.FILTER_ACCEPT
se o nó de texto não estiver vazio, o que leva à inclusão desse nó na lista de nós em que o iterador estará iterando. Ao contrário, o NodeFilter.FILTER_REJECT
constante é retornado para excluir os nós de texto vazios da lista iterável de nós.
Como usar o TreeWalker
API
Como mencionei antes, o NodeIterator
e TreeWalker
APIs são semelhantes uns aos outros.
TreeWalker
pode ser criado usando o createTreeWalker ()
método do documento
interface. Esse método, assim como createNodeFilter ()
, leva três argumentos: o nó raiz, um filtro predefinido e um filtro personalizado.
Se nós use o TreeWalker
API em vez de NodeIterator
o trecho de código anterior é semelhante ao seguinte:
var div = document.querySelector ('# wrapper'); var treeWalker = document.createTreeWalker (div, NodeFilter.SHOW_TEXT, função (nó) return (node.nodeValue.trim ()! == "")? NodeFilter.FILTER_ACCEPT: NodeFilter.FILTER_REJECT;); while (treeWalker.nextNode ()) console.log (treeWalker.currentNode.nodeValue.trim ()); / * output [Log] este é o wrapper da página [Log] Olá [Log] Como você está? * /
Ao invés de referenceNode
, a currentNode
propriedade do TreeWalker
API é usada para acessar o nó ao qual o iterador está atualmente conectado. Em adição ao nextNode ()
método, Treewalker
tem outros métodos úteis. o previousNode ()
método (também presente em NodeIterator
) retorna o nó anterior do nó o iterador está atualmente ancorado para.
Uma funcionalidade semelhante é executada pelo parentNode ()
, primeiro filho()
, lastChild ()
, previousSibling ()
, e nextSibling ()
métodos. Esses métodos são disponível apenas no TreeWalker
API.
Aqui está um exemplo de código que gera o último filho do nó o iterador está ancorado para:
var div = document.querySelector ('# wrapper'); var treeWalker = document.createTreeWalker (div, NodeFilter.SHOW_ELEMENT); console.log (treeWalker.lastChild ()); / * saída [log]Como você está?
* /
Qual API escolher
Escolha o NodeIterator
API, quando você precisa apenas de um simples iterador para filtrar e percorrer os nós selecionados. E escolha o TreeWalker
API, quando você precisa acessar a família dos nós filtrados, como seus irmãos imediatos.