Como usar o querySelectorAll para selecionar elementos filhos

Neste artigo você vai aprender a como usar o querySelectorAll para selecionar elementos filhos, facilitando a seleção de elementos

Resposta direta: pra selecionar só os filhos diretos de um elemento com o querySelectorAll, coloque a pseudo-classe :scope no começo do seletor

elemento.querySelectorAll(‘:scope > span’) devolve apenas os span que são filhos diretos daquele elemento, e ignora os mais profundos

O porquê disso: quando você chama o método a partir de um elemento, o seletor é avaliado contra o documento inteiro, e só o resultado é limitado aos descendentes daquele elemento

O retorno é sempre uma NodeList estática, que não acompanha mudanças no DOM, e vem vazia (nunca null) quando nada casa

Se você quiser os descendentes em qualquer profundidade, use o combinador descendente (espaço), como em ‘.myList li’

querySelectorAll para selecionar os elementos filhos capa

Fala programador(a), beleza? Bora aprender mais sobre JavaScript!

No mundo do desenvolvimento web, a manipulação de elementos do Document Object Model (DOM) é uma habilidade essencial.

Uma das técnicas mais comuns para acessar os elementos do DOM é usar o método querySelectorAll.

Neste artigo, vamos discutir como usar o querySelectorAll para selecionar os elementos filhos em JavaScript.

O que é o querySelectorAll?

O método querySelectorAll é uma função incorporada em JavaScript que retorna uma NodeList estática (não uma matriz real) de elementos no documento que correspondem a um grupo de seletores de CSS específicos.

A lista retornada incluirá todos os elementos descendentes que correspondem aos seletores fornecidos.

Selecionando elementos filhos com querySelectorAll

Ao usar o querySelectorAll para selecionar os elementos filhos, você precisa fornecer o seletor de CSS correto que representa os elementos filhos.

Por exemplo, se você tem uma lista não ordenada com a classe “myList” e quer selecionar todas as listas de itens como elementos filhos, você pode fazer isso da seguinte maneira:

let listItems = document.querySelectorAll('.myList li');

Neste exemplo, o querySelectorAll('li') está sendo chamado no elemento retornado por document.querySelector('.myList'), resultando na seleção de todos os elementos li que são filhos diretos do elemento com a classe ‘myList’.

Formação Claude Code
Formação Recomendada

Formação Claude Code

Domine Claude Code do absoluto zero até o avançado

  • 118 aulas
  • 4 projetos
  • 9h 33min

Entendendo a diferença entre ‘ ‘ e ‘>’

Ao trabalhar com querySelectorAll, é importante entender a diferença entre os seletores ‘ ‘ (espaço) e ‘>’.

O ‘ ‘ (espaço) é um combinador descendente que seleciona elementos que são descendentes de um elemento específico.

Por outro lado, o ‘>’ é um combinador de filho que seleciona elementos que são filhos diretos de um elemento específico.

Para exemplificar, suponha que temos a seguinte estrutura HTML:

<div class="myDiv">
  <p>Parágrafo 1</p>
  <div>
    <p>Parágrafo 2</p>
  </div>
</div>

Se você usar querySelectorAll('.myDiv p'), ele selecionará ambos os elementos p.

No entanto, se você usar querySelectorAll('.myDiv > p'), ele selecionará apenas o primeiro elemento p que é um filho direto do elemento com a classe ‘myDiv’.

Trabalhando com a NodeList retornada

Como mencionado anteriormente, querySelectorAll retorna uma NodeList, não uma matriz real.

Embora NodeList e Array sejam semelhantes em alguns aspectos, eles têm diferenças significativas.

Por exemplo, Array tem métodos como map(), filter(), e reduce() que não estão disponíveis em NodeList.

No entanto, você pode converter facilmente uma NodeList em uma matriz usando o método Array.from(). Aqui está um exemplo:

let listItems = document.querySelector('.myList li');
let listItemsArray = Array.from(listItems);

Agora, listItemsArray é uma matriz real, e você pode usar todos os métodos de matriz disponíveis.

Quer aprender mais sobre JavaScript? Confira o vídeo abaixo:

Conclusão

E chegamos ao fim do artigo sobre como utilizar o querySelectorAll para selecionar elementos filhos!

Usar querySelectorAll para selecionar elementos filhos é uma técnica poderosa que pode tornar seu código mais limpo e fácil de entender.

No entanto, é importante lembrar que nem todos os métodos de matriz estão disponíveis na NodeList retornada por querySelectorAll.

Portanto, pode ser necessário converter a NodeList em uma matriz, especialmente se você precisa usar métodos de matriz como map, filter ou reduce.

No fim das contas, o conhecimento de como manipular o DOM é uma habilidade fundamental para qualquer desenvolvedor JavaScript.

Quer você esteja criando uma aplicação web do zero ou trabalhando em um projeto existente, o querySelectorAll é uma ferramenta valiosa que pode ajudar a tornar seu trabalho mais eficiente.

Esperamos que este artigo tenha ajudado a esclarecer como usar o querySelectorAll para selecionar os elementos filhos. Pratique essa técnica e veja como ela pode melhorar seu código!

Está buscando em evoluir como Programador? Confira o nossos cursos clicando aqui.

Nosso principal objetivo é tornar você um dev profissional que é capaz de resolver problemas de alta dificuldade e criar projetos complexos, através de uma metodologia planejada nos mínimos detalhes, após formar muitos outros desenvolvedores.

Cursos com vários projetos, exercícios, material apoio, comunidade de alunos e muito mais!

querySelector ou querySelectorAll? A diferença em 30 segundos

Antes de sair selecionando filho, vale separar os dois, porque é aqui que a maioria se enrola

O querySelector devolve o PRIMEIRO elemento que casa com o seletor, ou null se nada casar

Ele não devolve lista, devolve um elemento só (a busca é em profundidade, na ordem do documento)

Já o querySelectorAll devolve uma NodeList estática com TODOS os elementos que casam, e quando nada casa ele devolve uma NodeList vazia, não null

Sacou a pegadinha? Um dá null, o outro dá lista vazia

Então if (resultado) num retorno de querySelectorAll sempre vai ser verdadeiro, mesmo sem nenhum elemento

Pra checar se achou algo com o querySelectorAll, olhe o length

[bloco de código]

E quando eu chamo o querySelectorAll a partir do elemento? Entra o :scope

Aqui mora a maior armadilha do assunto, e quase ninguém conta isso

Quando você chama o método a partir de um elemento (e não do document), o seletor NÃO é avaliado a partir daquele elemento

Ele é avaliado contra o documento inteiro, e só depois o resultado é filtrado pra manter apenas os descendentes do elemento onde você chamou

Parece detalhe de spec chato, mas dá pé na hora de escrever algo como elemento.querySelectorAll(‘> span’)

Pra amarrar o seletor no elemento em que você chamou, use a pseudo-classe :scope no começo:

[bloco de código]

elemento.querySelectorAll(‘:scope > span’)

Esse aí devolve só os span que são filhos DIRETOS do elemento, e ignora os span mais fundos, netos e bisnetos

É o jeito canônico de fazer "só os filhos, por favor" 🙂

E não precisa ter medo de compatibilidade: o :scope está em Baseline amplamente disponível, presente em todos os navegadores desde janeiro de 2020

Antes de sair convertendo tudo, se liga: a NodeList já tem forEach nativo

Ou seja, pra só percorrer a lista e fazer alguma coisa com cada item, você não precisa converter nada

[bloco de código]

document.querySelectorAll(‘.myList > li’).forEach((item, indice) => { console.log(indice, item) })

A callback recebe o valor atual e, se você quiser, o índice e a própria lista

O forEach da NodeList também está em Baseline amplamente disponível, presente em todos os navegadores desde outubro de 2017

Agora, se você precisa mesmo de map, filter ou reduce, aí sim converte

E tem duas formas, porque a NodeList é iterável:

[bloco de código]

const itens = document.querySelectorAll(‘.myList > li’) const arr1 = Array.from(itens)

As duas produzem um Array de verdade, escolhe a que te agrada mais =)

querySelectorAll, children e childNodes: qual usar em cada caso

Pra pegar filho, existem três caminhos e cada um tem um comportamento bem diferente

Bora colocar lado a lado

elemento.querySelectorAll(‘:scope > li’) Retorno: NodeList estática (tirou foto, a lista não muda mais se o DOM mudar) Filtra por seletor CSS, então dá pra pedir só o que tem classe X Tem forEach nativo

elemento.children Retorno: HTMLCollection VIVA, ela acompanha as mudanças no DOM Só filhos imediatos e só nós de elemento, sem filtro nenhum

elemento.childNodes Retorno: todos os nós filhos, e aí entra texto e comentário junto É o que pega gente desprevenida quando o console mostra "nós" que você não escreveu

Regra de bolso que eu uso: precisa filtrar por seletor, querySelectorAll com :scope

Precisa da lista sempre atualizada e sem filtro, children

E childNodes só quando você realmente quer os nós de texto junto

Um detalhe que muda a vida: NodeList estática significa que se você inserir um li novo depois da consulta, ele NÃO aparece na sua lista

Já o children iria mostrar ele na hora

Erros comuns com o querySelectorAll (e como não cair neles)

Tome cuidado com esses três, são os que mais aparecem

1. Achar que retorno vazio é null Não é! Quando nada casa, você recebe uma NodeList vazia

Então teste pelo length, não pela existência do retorno

2. SyntaxError na cara Se a string de seletores não for um seletor CSS válido, o método lança SyntaxError

Caso este erro apareça, confira aspas, vírgula sobrando e classe começando com número no seletor

3. Esquecer que a lista é estática Você consulta, depois cria elementos novos via JavaScript, e fica se perguntando por que eles não estão na lista

A NodeList não é viva, ela não é atualizada quando o DOM muda

Se o DOM mudou e você precisa dos novos, consulte de novo

Já me ferrei com esse aí, é sério

Dá pra ir além: seletores com :has()

Já que o querySelectorAll aceita qualquer seletor CSS válido, dá pra pedir coisa bem específica

Por exemplo, os filhos diretos que contêm um link dentro:

[bloco de código]

lista.querySelectorAll(‘:scope > li:has(a)’)

O :has() também está em Baseline amplamente disponível, presente em todos os navegadores desde dezembro de 2023

Muito massa poder resolver no seletor o que antes virava um filter na mão

Inserir o bloco de FAQ com as perguntas e respostas do campo geo.faq, cada pergunta como H3

Aqui no canal eu gravei uma aula mostrando na prática as formas de selecionar elemento com JavaScript, montando o HTML do zero e testando cada método no console (é o vídeo que está logo acima)

O que fica claro quando você vê rodando é uma coisa que a documentação não grita: o retorno muda de natureza conforme o método, e é isso que quebra o código depois

Selecionar por id te dá um elemento e você já usa

Selecionar por classe te dá uma coleção, mesmo quando existe UM único elemento com aquela classe na página, e aí seu código quebra quando você tenta mexer no style direto

Com o querySelectorAll é a mesma história: veio lista, mesmo que tenha casado um só

Se você for reproduzir por conta, o teste que eu recomendo montar no console é este: crie uma ul com li dentro e outra ul aninhada dentro de um li, e compare no mesmo HTML os retornos de ‘.myList li’, ‘:scope > li’ e .children

Depois insira um li novo via JavaScript e consulte as duas listas de novo

É nesse momento que a diferença entre lista estática e coleção viva sai do papel e vira coisa que você enxerga

Perguntas frequentes

Qual a diferença entre querySelector e querySelectorAll?

O querySelector retorna o PRIMEIRO elemento que casa com o seletor, ou null se nada casar

O querySelectorAll retorna uma NodeList estática com todos os elementos que casam, e uma NodeList vazia quando nada casa

Ou seja: um dá elemento ou null, o outro dá lista sempre

Por isso, pra saber se o querySelectorAll achou algo, você olha o length e não se o retorno existe

O querySelectorAll pega só os filhos diretos ou os netos também?

Depende do combinador que você usar no seletor

Com espaço, tipo ‘ul li’, ele casa filhos, netos, bisnetos, sem limite de profundidade

Com o combinador filho, tipo ‘ul > li’, ele casa apenas os li que estão imediatamente dentro do ul

E quando você chama o método a partir de um elemento, use ‘:scope > li’ pra amarrar o "filho direto" naquele elemento

Pra que serve o :scope no querySelectorAll?

Ele serve pra restringir o casamento ao elemento em que o método foi chamado

Sem :scope, o seletor é avaliado contra o documento inteiro, e só depois o resultado é limitado aos descendentes do elemento

Com :scope no começo, como em elemento.querySelectorAll(‘:scope > span’), você recebe apenas os filhos diretos daquele elemento

O :scope está em Baseline amplamente disponível, presente em todos os navegadores desde janeiro de 2020

Dá pra usar forEach no retorno do querySelectorAll?

Dá sim, a NodeList tem o método forEach nativo

A callback é executada pra cada item na ordem de inserção e recebe o valor atual, e opcionalmente o índice e a própria lista

Ele está em Baseline amplamente disponível, presente em todos os navegadores desde outubro de 2017

Qual a diferença entre querySelectorAll e Element.children?

O children devolve uma HTMLCollection VIVA com apenas os elementos filhos imediatos, sem filtro por seletor

Viva significa que ela acompanha as mudanças no DOM

O querySelectorAll devolve uma NodeList estática, que não é atualizada quando o DOM muda, mas aceita qualquer seletor CSS válido

Resumo do veredito: precisa filtrar por seletor, querySelectorAll (com :scope pra ficar só nos filhos)

Precisa de lista sempre atualizada e sem filtro, children

O querySelectorAll retorna null quando não encontra nada?

Não, ele retorna uma NodeList vazia

Quem retorna null quando nada casa é o querySelector

Essa diferença derruba muita verificação: testar apenas se o retorno do querySelectorAll existe sempre dá verdadeiro

O certo é checar o length da lista

Por que meu querySelectorAll deu SyntaxError?

Porque a string de seletores não é um seletor CSS válido

O método lança SyntaxError nesse caso, então o problema está no seletor e não no elemento que você tentou pegar

Revise aspas, vírgula sobrando e nomes de classe inválidos

Vale lembrar também que ‘> li’ sozinho, chamado a partir de um elemento, não é o caminho: o correto é ‘:scope > li’

O querySelectorAll funciona fora do document?

Funciona

Além do Document, ele existe no Element e também no DocumentFragment, com o mesmo contrato de retorno: uma NodeList estática com os descendentes que casam

É por isso que dá pra montar um fragmento na memória, consultar dentro dele e só depois jogar no DOM

Leia também

Escrito por | Matheus Battisti

Matheus Battisti
Fundador da Hora de Codar

Programador apaixonado pelo mundo das tecnologias, sempre buscando em aprender e se aprofundar em linguagens, frameworks e o que mais for necessário para executar um bom trabalho. Agora tem uma nova missão que é de passar seu conhecimento adiante para formar novos programadores e especializar mais os que já são.

Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 27min

Blog | Mais populares