Manipulação do DOM
O DOM (Document Object Model) é uma árvore que o navegador cria a partir do documento HTML. Operando nessa árvore com JavaScript, você pode mudar dinamicamente o conteúdo, a estrutura e os atributos da página — como colher frutas de uma árvore, enxertar novos galhos ou podar madeira morta.
Selecionando Elementos
O primeiro passo na manipulação do DOM é sempre "encontrar primeiro".
| Método | Retorna | Descrição |
|---|---|---|
getElementById('id') |
Elemento único | Mais rápido, id é único |
getElementsByClassName('cls') |
HTMLCollection | Coleção ao vivo, sincroniza com mudanças no DOM |
getElementsByTagName('tag') |
HTMLCollection | Igual ao anterior |
querySelector('seletor') |
Elemento único | Seletor CSS, retorna o primeiro que combina |
querySelectorAll('seletor') |
NodeList | Coleção estática, não muda com o DOM |
querySelector vs getElementBy*: a primeira usa seletores CSS (mais flexível), a segunda tem desempenho levemente melhor. Para o dia a dia, prefira querySelector — é mais intuitivo.
Exemplo: Comparando os Cinco Métodos de Seleção
<div id="box" class="card active">Olá</div>
<div class="card">Mundo</div>
<p class="card">JS</p>
<script>
const porId = document.getElementById('box');
console.log('porId:', porId.textContent);
const porClasse = document.getElementsByClassName('card');
console.log('porClasse contagem:', porClasse.length);
const porTag = document.getElementsByTagName('p');
console.log('porTag:', porTag[0].textContent);
const primeiro = document.querySelector('.card');
console.log('querySelector:', primeiro.textContent);
const todos = document.querySelectorAll('.card');
console.log('querySelectorAll contagem:', todos.length);
</script>
Modificando Conteúdo
Depois de encontrar um elemento, a necessidade mais comum é mudar "o que ele diz".
textContent: lê/escreve texto puro, seguro e eficiente.innerHTML: lê/escreve strings HTML, pode inserir tags, mas tem risco de XSS.
innerHTML para inserir conteúdo fornecido pelo usuário, senão atacantes podem injetar scripts maliciosos. É como afixar uma carta de um diretamente no mural — a carta pode conter uma "bomba".
Exemplo: textContent vs innerHTML
<div id="safe"></div>
<div id="danger"></div>
<script>
const safe = document.getElementById('safe');
safe.textContent = '<b>Isto não ficará em negrito</b>';
const danger = document.getElementById('danger');
danger.innerHTML = '<b>Isto ficará em negrito</b>';
</script>
Modificando Atributos
Atributos de elementos HTML (id, class, src, href, etc.) também podem ser lidos e escritos com JS.
| Método | Descrição |
|---|---|
getAttribute('nome') |
Ler valor do atributo |
setAttribute('nome', 'valor') |
Definir atributo |
removeAttribute('nome') |
Remover atributo |
el.id, el.className, el.src. Mas para atributos customizados (data-*), use getAttribute ou el.dataset.
Exemplo: Manipulando Atributos de Link
<a id="link" href="https://example.com" target="_blank">Link de Exemplo</a>
<script>
const link = document.getElementById('link');
console.log('href:', link.getAttribute('href'));
link.setAttribute('href', 'https://mdn.io');
link.setAttribute('title', 'Clique para ir ao MDN');
link.removeAttribute('target');
console.log('Após modificação:', link.getAttribute('href'));
</script>
Criando e Inserindo Elementos
Uma das habilidades centrais de manipulação do DOM: "criar" um elemento do nada, depois conectá-lo à árvore.
| Método | Descrição |
|---|---|
createElement('tag') |
Criar nó de elemento |
createTextNode('texto') |
Criar nó de texto |
appendChild(filho) |
Anexar ao final |
insertBefore(novo, ref) |
Inserir antes de ref |
Exemplo: Adicionando Itens de Lista Dinamicamente
<ul id="list">
<li>Item existente</li>
</ul>
<script>
const lista = document.getElementById('list');
const li = document.createElement('li');
li.textContent = 'Item adicionado recentemente';
lista.appendChild(li);
const li2 = document.createElement('li');
li2.textContent = 'Inserido no início';
lista.insertBefore(li2, lista.firstChild);
</script>
Removendo e Clonando Elementos
| Método | Descrição |
|---|---|
removeChild(filho) |
Pai remove nó filho |
remove() |
Elemento remove a si mesmo (API mais recente) |
cloneNode(true/false) |
true = clone profundo (incluindo filhos), false = clone raso |
remove() é mais simples que removeChild(), mas se você precisar obter o nó removido para processamento posterior, use removeChild() — ele retorna o nó removido.
Exemplo: Removendo e Clonando
<ul id="fruits">
<li>Maçã</li>
<li>Banana</li>
<li>Laranja</li>
</ul>
<script>
const frutas = document.getElementById('fruits');
const banana = frutas.children[1];
const removido = frutas.removeChild(banana);
console.log('Removido:', removido.textContent);
const clone = frutas.cloneNode(true);
document.body.appendChild(clone);
console.log('Lista clonada');
</script>
📖 Resumo
- Dois campos para selecionar elementos:
getElementBy*(melhor desempenho) equerySelector*(mais flexível). Para o dia a dia,querySelectoré suficiente. - Use
textContentpara alterações de texto, useinnerHTMLapenas quando precisar de HTML. Este último requer prevenção de XSS. - Operações com atributos:
getAttributepara ler,setAttributepara escrever,removeAttributepara excluir. - Fluxo padrão para criar elementos:
createElement→ definir conteúdo/atributos →appendChildpara montar. - Duas formas de remover elementos:
remove()(elemento remove a si mesmo),removeChild()(pai remove e você recebe o nó de volta). cloneNode(true)clona profundamente incluindo todos os descendentes,cloneNode(false)clona apenas a casca.
❓ Perguntas Frequentes
P: O que acontece se
querySelectorretornarnull? R: Chamar qualquer propriedade/método emnulllançará umTypeError. Então é melhor verificar antes de operar:const el = document.querySelector('.xxx'); if (el) { ... }.
P: Qual a diferença entre
HTMLCollectioneNodeList? R:HTMLCollectioné ao vivo — atualiza automaticamente quando o DOM muda;NodeListdequerySelectorAllé um snapshot estático. Ao iterar e adicionar/remover elementos, uma coleção estática é mais segura, senão você pode entrar em loop infinito.
P: O que acontece se você fizer
appendChildde um nó que já existe? R: O nó "se move" da posição original para a nova posição. No DOM, o mesmo nó só pode aparecer uma vez. Isso é uma cópia, não uma movimentação.
📝 Atividades
- Básico: Crie uma página que use
createElementeappendChildpara gerar dinamicamente uma lista contendo 5 nomes de cidades. - Intermediário: Adicione um botão de exclusão à lista do exercício anterior. Quando clicado, use
removeChildpara excluir o item da lista correspondente. - Desafio: Implemente um simples "gerenciador de notas" — um campo de input + botão de adicionar. Cada vez que você adicionar uma nota, crie um cartão com um botão de exclusão. Clicar no botão de exclusão remove aquele cartão.



