Mesmo na era de frameworks reativos como React, Vue e Angular, compreender a manipulação nativa do DOM é uma habilidade fundamental para qualquer desenvolvedor frontend. É essa base que permite entender o que acontece "sob o capô" das bibliotecas modernas, além de ser a solução ideal para projetos leves em Vanilla JavaScript. As APIs modernas do navegador são elegantes e poderosas, tornando o antigo jQuery praticamente desnecessário.

Selecionando Elementos no DOM

Esqueça os seletores complexos. Com o padrão moderno, você consegue buscar qualquer elemento utilizando a mesma sintaxe de seletores do CSS.

Seletores Modernos
// Selecionar um único elemento
const header = document.querySelector('.header');
const submitBtn = document.getElementById('submit-btn');
const firstArticle = document.querySelector('article:first-of-type');

// Selecionar múltiplos elementos (retorna uma NodeList)
const cards = document.querySelectorAll('.card');
const links = document.querySelectorAll('nav a');

// Iterar sobre uma NodeList diretamente
cards.forEach(card => {
  card.classList.add('loaded');
});

// Converter para Array para usar métodos como filter ou map
const cardArray = [...document.querySelectorAll('.card')];
const visibleCards = cardArray.filter(c => !c.hidden);

Modificando Elementos e Atributos

Alterar o conteúdo, estilos e comportamentos de um elemento é simples e direto com as propriedades nativas.

Conteúdo, Atributos e Classes
const el = document.querySelector('.hero-title');

// Alterar texto (seguro contra injeção de HTML)
el.textContent = 'Olá, Mundo!';

// Alterar HTML (⚠️ Use com cuidado para evitar ataques XSS)
el.innerHTML = '<strong>Bem-vindo</strong> ao site!';

// Manipulação de Atributos
el.setAttribute('role', 'heading');
el.getAttribute('data-id');
el.removeAttribute('hidden');

// Uso de Dataset (atributos data-*)
el.dataset.userId = '123';    // Define data-user-id="123"
console.log(el.dataset.userId); // Retorna "123"

// Gerenciamento de Classes CSS
el.classList.add('active', 'visible');
el.classList.remove('loading');
el.classList.toggle('dark-mode');
el.classList.contains('active');  // true/false
el.classList.replace('old-class', 'new-class');

// Estilos Inline
el.style.color = '#6366f1';
el.style.setProperty('--accent', '#22d3ee');

Criação e Inserção Dinâmica

Adicionar novos elementos à página em tempo de execução é essencial para interfaces dinâmicas.

Criação Dinâmica de Elementos
// Criar um novo elemento
const card = document.createElement('div');
card.className = 'card';
card.innerHTML = `
  <h3>${title}</h3>
  <p>${description}</p>
`;

// Inserir no DOM
container.appendChild(card);                    // Ao final do container
container.prepend(card);                        // No início do container
container.insertBefore(card, referenceElement); // Antes de um elemento específico

// Métodos modernos de inserção
element.before(newElement);    // Antes do elemento
element.after(newElement);     // Depois do elemento
element.replaceWith(newElement); // Substitui o elemento atual

// Remover do DOM
element.remove();

// Clonar um elemento
const clone = template.cloneNode(true); // true realiza uma cópia profunda

Gerenciamento de Eventos

Interatividade é o coração da web. O método addEventListener é a forma padrão de ouvir interações do usuário.

addEventListener e Eventos Comuns
const button = document.querySelector('#submit');

// Adicionar um ouvinte de evento
button.addEventListener('click', (event) => {
  event.preventDefault(); // Evita o comportamento padrão
  console.log('Botão clicado!', event.target);
});

// Remover evento (requer uma função nomeada)
function handleClick(e) { /* lógica */ }
button.addEventListener('click', handleClick);
button.removeEventListener('click', handleClick);

// Eventos mais utilizados
element.addEventListener('input', handler);     // Mudanças em tempo real em inputs
element.addEventListener('change', handler);    // Quando o input perde o foco
element.addEventListener('submit', handler);    // Envio de formulários
element.addEventListener('keydown', handler);   // Tecla pressionada
element.addEventListener('scroll', handler);    // Rolagem da página
window.addEventListener('load', handler);       // Quando tudo foi carregado

Delegação de Eventos

Em vez de adicionar ouvintes a centenas de elementos filhos, adicione um único ouvinte ao pai e use event.target. Isso economiza memória e funciona com elementos adicionados dinamicamente via JavaScript.

Padrão de Delegação de Eventos
// ❌ Abordagem Ineficiente — um listener para cada item
document.querySelectorAll('.card').forEach(card => {
  card.addEventListener('click', handleCardClick);
});

// ✅ Abordagem Otimizada — um único listener no container pai
document.querySelector('.card-grid').addEventListener('click', (e) => {
  const card = e.target.closest('.card');
  if (!card) return; // Se o clique não foi em um card, ignora

  const id = card.dataset.id;
  handleCardClick(id);
});

Uso da Tag Template

A tag HTML <template> permite armazenar fragmentos de marcação que não são renderizados até que você os ative via script.

Trabalhando com <template>
<!-- Template HTML (invisível na renderização inicial) -->
<template id="card-template">
  <div class="card">
    <h3 class="card-title"></h3>
    <p class="card-desc"></p>
  </div>
</template>

<script>
const template = document.getElementById('card-template');

function addCard(title, desc) {
  const clone = template.content.cloneNode(true);
  clone.querySelector('.card-title').textContent = title;
  clone.querySelector('.card-desc').textContent = desc;
  document.querySelector('.grid').appendChild(clone);
}
</script>

Dicas de Performance no DOM

  • Agrupe atualizações do DOM — Utilize DocumentFragment para realizar múltiplas inserções de uma só vez, evitando reflows excessivos.
  • Prefira delegação de eventos em listas longas para reduzir o consumo de memória.
  • Evite o "Layout Thrashing" — Não alterne entre ler propriedades de layout (como offsetHeight) e escrever estilos (como style.height) dentro de loops.
  • Use requestAnimationFrame para animações ou atualizações visuais complexas.
  • Aplique Debounce ou Throttle em eventos que disparam muito rápido, como scroll e resize.

Otimize seu Código com Nossas Ferramentas

Acelere seu desenvolvimento com nossos minificadores e formatadores gratuitos.