Nesta aula, você aprenderá como selecionar elementos do DOM (Document Object Model) em JavaScript, uma habilidade essencial para manipular páginas web dinamicamente. Vamos explorar os métodos mais comuns: getElementById, querySelector e querySelectorAll, e entender a diferença entre coleções vivas (live) e estáticas (static), que impacta o comportamento do seu código.

Selecionar elementos corretamente é o primeiro passo para interagir com o conteúdo HTML, alterar estilos, adicionar eventos e muito mais. Compreender as nuances de cada método evita bugs e melhora a performance.

getElementById

O método getElementById é um dos mais rápidos e específicos para selecionar um único elemento pelo seu atributo id. Como os IDs devem ser únicos na página, esse método retorna diretamente o elemento ou null se não existir.

Sintaxe: document.getElementById('meuId'). É importante notar que o argumento é uma string sem o caractere #. Esse método está disponível apenas no objeto document.

// HTML: <div id="container">Conteúdo</div>
const container = document.getElementById('container');
console.log(container.textContent); // "Conteúdo"

Boa prática: sempre verifique se o elemento existe antes de manipulá-lo, especialmente em páginas dinâmicas.

querySelector / querySelectorAll

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

Sintaxe: document.querySelector('.minha-classe') e document.querySelectorAll('div p'). Eles podem ser chamados em qualquer elemento, não apenas no document, permitindo buscas contextuais.

// HTML: <ul class="lista"><li>Item 1</li><li>Item 2</li></ul>
const lista = document.querySelector('.lista');
const primeiroItem = lista.querySelector('li'); // busca apenas dentro da lista
const todosItens = document.querySelectorAll('.lista li');
console.log(todosItens.length); // 2

Dica: use seletores específicos para evitar ambiguidades, mas lembre-se de que seletores complexos podem ser menos performáticos que getElementById.

Coleções vivas vs estáticas

Entender se uma coleção é viva (live) ou estática (static) é crucial para prever o comportamento do código. Coleções vivas refletem mudanças no DOM automaticamente, enquanto coleções estáticas são uma fotografia do momento da consulta.

getElementsByTagName, getElementsByClassName e children (por exemplo) retornam coleções vivas (HTMLCollection). Já querySelectorAll retorna uma NodeList estática. Veja o exemplo:

// HTML: <ul id="lista"><li>A</li></ul>
const itensVivos = document.getElementsByTagName('li');
const itensEstaticos = document.querySelectorAll('li');

console.log(itensVivos.length); // 1
console.log(itensEstaticos.length); // 1

// Adiciona um novo li
document.getElementById('lista').innerHTML += '<li>B</li>';

console.log(itensVivos.length); // 2 (viva!)
console.log(itensEstaticos.length); // 1 (estática, não atualizou)

Implicações: se você precisar iterar sobre uma coleção viva enquanto modifica o DOM, pode haver efeitos colaterais (como loops infinitos). Prefira coleções estáticas quando fizer múltiplas iterações ou quando o DOM for alterado após a seleção. Além disso, NodeList de querySelectorAll possui o método forEach, enquanto HTMLCollection não (mas pode ser convertido com Array.from).

Boas práticas

  • Use getElementById para selecionar um único elemento com ID, pois é o mais rápido.
  • Use querySelector para selecionar o primeiro elemento que corresponda a um seletor CSS complexo.
  • Use querySelectorAll para obter uma lista estática de elementos, especialmente se o DOM for modificado depois.
  • Evite reconsultas desnecessárias: armazene referências em variáveis quando for reutilizar um elemento.
  • Cuidado com coleções vivas em loops: faça uma cópia estática se necessário.

Referências

Exercícios

  1. Crie um HTML com um elemento <div id="app"></div>. Use JavaScript para selecioná-lo e alterar seu texto para "Olá, mundo!".
  2. ✓ Resposta:
    const app = document.getElementById('app');
    app.textContent = 'Olá, mundo!';
  3. Dado o HTML <ul class="menu"><li>Home</li><li>Sobre</li></ul>, selecione o primeiro li usando querySelector e altere seu texto para "Início".
  4. ✓ Resposta:
    const primeiroLi = document.querySelector('.menu li');
    primeiroLi.textContent = 'Início';
  5. Selecione todos os elementos com a classe .item (suponha que existam 3) e adicione a classe .destaque a eles usando querySelectorAll.
  6. ✓ Resposta:
    const itens = document.querySelectorAll('.item');
    itens.forEach(item => item.classList.add('destaque'));
  7. Crie um HTML com uma lista <ul id="lista"><li>1</li></ul>. Use getElementsByTagName para obter os li (coleção viva). Adicione um novo li via innerHTML e mostre no console o tamanho da coleção antes e depois.
  8. ✓ Resposta:
    const lis = document.getElementsByTagName('li');
    console.log(lis.length); // 1
    document.getElementById('lista').innerHTML += '<li>2</li>';
    console.log(lis.length); // 2 (coleção viva)
  9. Explique com suas palavras e um exemplo a diferença entre coleção viva e estática.
  10. ✓ Resposta:Coleções vivas (como as retornadas por getElementsByTagName) são atualizadas automaticamente quando o DOM muda. Coleções estáticas (como as retornadas por querySelectorAll) são uma fotografia do momento. Exemplo: se você seleciona todos os li de uma lista e depois adiciona um novo li, a coleção viva terá tamanho 2, enquanto a estática ainda terá tamanho 1.