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’

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
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
Formações
Formação Vibe Coding
Do Prompt ao Produto: Crie Software Real com IA
- 474 aulas
- 20 projetos
- 39h 27min
Blog | Mais populares
As diferenças de var, let e const

Como redirecionar para outra página com JavaScript
Exercícios de lógica de programação JavaScript com gabarito
Quais são os melhores exercícios lógica de programação JavaScript? Colocar em prática os exercícios de lógica de programação em JavaScript é de extrema importância para […]
