Selecionar elementos no DOM é uma das tarefas mais comuns em JavaScript para interagir com páginas web. Nesta aula, vamos explorar os principais métodos de seleção e suas características, incluindo a diferença crucial entre coleções vivas e estáticas.

Dominar esses métodos é essencial para manipular conteúdo, estilos e eventos de forma eficiente.

getElementById

O método getElementById seleciona um único elemento com base no seu atributo id. Como os IDs devem ser únicos na página, este método retorna diretamente o elemento ou null se não existir.

Exemplo prático: suponha que temos um parágrafo com id="mensagem".

const elemento = document.getElementById('mensagem');
console.log(elemento.textContent); // exibe o texto do elemento

Este método é rápido e ideal para elementos únicos. Ele retorna uma referência direta ao elemento, não uma lista.

querySelector / querySelectorAll

Os métodos querySelector e querySelectorAll aceitam qualquer seletor CSS, oferecendo grande flexibilidade. querySelector retorna o primeiro elemento correspondente, enquanto querySelectorAll retorna uma NodeList (estática) com todos os elementos correspondentes.

Exemplo: selecionar o primeiro elemento com classe "destaque" e todos os parágrafos dentro de uma div.

const primeiro = document.querySelector('.destaque');
const todosParagrafos = document.querySelectorAll('div p');
console.log(todosParagrafos.length); // número de parágrafos

Diferente de getElementsByClassName (que retorna HTMLCollection viva), querySelectorAll retorna uma NodeList estática, o que evita problemas de desempenho em loops.

Coleções vivas vs estáticas

Coleções vivas (como HTMLCollection retornado por getElementsByClassName ou getElementsByTagName) refletem mudanças no DOM em tempo real. Se você adicionar ou remover elementos, a coleção é atualizada automaticamente. Já coleções estáticas (NodeList de querySelectorAll) são uma fotografia do DOM no momento da chamada; alterações posteriores não afetam a lista.

Exemplo de coleção viva:

const itens = document.getElementsByClassName('item');
console.log(itens.length); // 2
const novoItem = document.createElement('li');
novoItem.className = 'item';
document.body.appendChild(novoItem);
console.log(itens.length); // 3 (atualizado automaticamente)

Exemplo de coleção estática:

const itensEstaticos = document.querySelectorAll('.item');
console.log(itensEstaticos.length); // 2
const novoItem = document.createElement('li');
novoItem.className = 'item';
document.body.appendChild(novoItem);
console.log(itensEstaticos.length); // 2 (não atualiza)

Isso é importante para loops: se você modificar o DOM enquanto itera sobre uma coleção viva, pode ter efeitos colaterais inesperados. Prefira querySelectorAll para evitar surpresas.

Boas práticas

- Use getElementById para IDs únicos por desempenho.
- Use querySelector para seletores complexos que retornam um único elemento.
- Use querySelectorAll para listas, especialmente se for iterar e modificar o DOM.
- Evite getElementsByClassName e getElementsByTagName a menos que você precise de uma coleção viva e saiba o que está fazendo.

Referências

Exercícios

  1. Escreva código que selecione um elemento com id "cabecalho" e altere seu texto para "Novo cabeçalho".

    ✓ Resposta:
    const cabecalho = document.getElementById('cabecalho');
    cabecalho.textContent = 'Novo cabeçalho';
  2. Usando querySelectorAll, selecione todos os elementos com classe "item" e exiba o número deles no console.

    ✓ Resposta:
    const itens = document.querySelectorAll('.item');
    console.log(itens.length);
  3. Explique a diferença entre HTMLCollection e NodeList.

    ✓ Resposta: HTMLCollection é uma coleção viva (atualiza automaticamente) e contém apenas elementos; NodeList é geralmente estática (querySelectorAll) e pode conter outros tipos de nós (como texto).
  4. Dado o HTML <ul id="lista"><li>A</li><li>B</li></ul>, use getElementById para selecionar a lista e adicione um novo item "C".

    ✓ Resposta:
    const lista = document.getElementById('lista');
    const novoItem = document.createElement('li');
    novoItem.textContent = 'C';
    lista.appendChild(novoItem);
  5. Usando querySelector, selecione o primeiro elemento com classe "destaque" dentro de uma div com id "conteudo".

    ✓ Resposta:
    const elemento = document.querySelector('#conteudo .destaque');