<h2>Seleção de Elementos no DOM</h2>
<p>A base de qualquer manipulação do DOM é saber localizar os elementos certos. O JavaScript oferece vários métodos nativos, cada um com seu caso de uso específico. Os métodos mais modernos e eficientes são <code>querySelector()</code> e <code>querySelectorAll()</code>, que aceitam qualquer seletor CSS válido.</p>
<pre><code class="language-javascript">// Seleciona o primeiro elemento que corresponde ao seletor
const titulo = document.querySelector('h1');
const botao = document.querySelector('.btn-primary');
const campo = document.querySelector('#email');
// Seleciona todos os elementos que correspondem
const paragrafos = document.querySelectorAll('p');
const itens = document.querySelectorAll('[data-tipo="destaque"]');
// Retorna um NodeList - é possível iterar com forEach
paragrafos.forEach(paragrafo => {
console.log(paragrafo.textContent);
});</code></pre>
<p>Para casos específicos, você ainda encontrará <code>getElementById()</code>, <code>getElementsByClassName()</code> e <code>getElementsByTagName()</code> em código legado. A diferença principal é que esses últimos retornam HTMLCollections (dinâmicas) enquanto <code>querySelectorAll()</code> retorna NodeLists (estáticas), o que é geralmente preferível para evitar comportamentos inesperados durante iterações.</p>
<h2>Manipulação de Elementos</h2>
<h3>Modificando Conteúdo e Atributos</h3>
<p>Após selecionar um elemento, você pode modificar seu conteúdo, classes e atributos. As propriedades <code>textContent</code> e <code>innerHTML</code> são as mais usadas, com a diferença crítica de que <code>innerHTML</code> interpreta tags HTML enquanto <code>textContent</code> trata tudo como texto puro.</p>
<pre><code class="language-javascript">const elemento = document.querySelector('.mensagem');
// Modificar conteúdo (seguro para texto)
elemento.textContent = 'Olá, usuário!';
// Modificar conteúdo com HTML (cuidado com XSS)
elemento.innerHTML = '<strong>Importante:</strong> Verifique seus dados.';
// Modificar atributos individuais
elemento.setAttribute('data-status', 'ativo');
elemento.id = 'msg-principal';
// Trabalhar com classes
elemento.classList.add('destaque');
elemento.classList.remove('oculto');
elemento.classList.toggle('selecionado');
// Verificar se possui uma classe
if (elemento.classList.contains('erro')) {
console.log('Há um erro neste elemento');
}</code></pre>
<h3>Criando e Removendo Elementos</h3>
<p>Às vezes você precisa gerar novos elementos dinamicamente. O processo envolve criar o elemento, configurá-lo e inserir no DOM.</p>
<pre><code class="language-javascript">// Criar um novo elemento
const novoItem = document.createElement('li');
novoItem.textContent = 'Item adicionado dinamicamente';
novoItem.className = 'item-novo';
// Inserir ao final da lista
const lista = document.querySelector('ul');
lista.appendChild(novoItem);
// Inserir em posição específica
const primeiroItem = lista.querySelector('li');
lista.insertBefore(novoItem, primeiroItem);
// Remover elementos
novoItem.remove();
// Ou remover via parent
lista.removeChild(novoItem);</code></pre>
<h3>Modificando Estilos</h3>
<p>Você pode alterar estilos diretamente via propriedade <code>style</code>, mas a melhor prática é trabalhar com classes CSS. Ainda assim, há situações onde estilos inline são necessários.</p>
<pre><code class="language-javascript">const caixa = document.querySelector('.caixa');
// Modificar estilos inline (use com moderação)
caixa.style.backgroundColor = '#3498db';
caixa.style.padding = '20px';
caixa.style.display = 'block';
// Preferível: trabalhar com classes
caixa.classList.add('ativo');
// Obter valor computado de um estilo
const corFundo = window.getComputedStyle(caixa).backgroundColor;
console.log(corFundo);</code></pre>
<h2>Traversal e Navegação no DOM</h2>
<h3>Percorrendo a Árvore DOM</h3>
<p>Traversal significa navegar entre elementos relacionados: pais, filhos, irmãos. Isso é essencial quando você precisa acessar elementos de forma relativa em vez de absoluta.</p>
<pre><code class="language-javascript">const elemento = document.querySelector('.item');
// Acessar o elemento pai
const pai = elemento.parentElement;
console.log(pai.className);
// Acessar todos os filhos
const filhos = elemento.children; // HTMLCollection
elemento.childNodes; // inclui nós de texto
// Primeiro e último filho
const primeiro = elemento.firstElementChild;
const ultimo = elemento.lastElementChild;
// Elementos irmãos
const proximo = elemento.nextElementSibling;
const anterior = elemento.previousElementSibling;
// Navegar múltiplos níveis
const avô = elemento.parentElement.parentElement;</code></pre>
<h3>Buscas Relativas com querySelector</h3>
<p>Uma técnica poderosa é usar <code>querySelector</code> de forma relativa, começando de um elemento específico em vez de sempre partir do <code>document</code>.</p>
<pre><code class="language-javascript">const formulario = document.querySelector('form');
// Buscar elementos dentro do formulário
const emailField = formulario.querySelector('input[name="email"]');
const todos_inputs = formulario.querySelectorAll('input');
// Verificar se um elemento contém outro
const campo = formulario.querySelector('[type="text"]');
if (formulario.contains(campo)) {
console.log('O campo está dentro do formulário');
}
// Encontrar o elemento pai mais próximo que corresponde a um seletor
const linha = campo.closest('tr'); // útil para tabelas
const card = campo.closest('.card');</code></pre>
<p>O método <code>closest()</code> é extremamente valioso: ele sobe a árvore DOM procurando o primeiro ancestral que corresponde ao seletor. Isso elimina a necessidade de escrever loops manuais para navegação.</p>
<h2>Boas Práticas e Performance</h2>
<p>Acessar o DOM é operação custosa. Minimize queries desnecessárias armazenando referências em variáveis. Ao manipular múltiplos elementos, agrupe as mudanças para evitar reflows contínuos.</p>
<pre><code class="language-javascript"></code></pre>
<h2>Conclusão</h2>
<p>Dominar o DOM é fundamental para qualquer desenvolvedora ou desenvolvedor JavaScript. Os três pilares aprendidos neste artigo são: <strong>(1) seleção eficiente com <code>querySelector</code> e <code>querySelectorAll</code></strong>, que cobrem 95% dos casos reais; <strong>(2) manipulação segura de conteúdo, classes e atributos</strong>, sempre preferindo classes para estilos em vez de estilos inline; e <strong>(3) traversal inteligente usando <code>parentElement</code>, <code>closest()</code> e buscas relativas</strong>, que torna seu código mais flexível e resiliente a mudanças estruturais no HTML.</p>
<p>Com esses conhecimentos e as práticas de performance, você está pronto para construir interfaces dinâmicas e responsivas.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://developer.mozilla.org/pt-BR/docs/Web/API/Document_Object_Model" target="_blank" rel="noopener noreferrer">MDN Web Docs - Document Object Model (DOM)</a></li>
<li><a href="https://developer.mozilla.org/pt-BR/docs/Web/API/Document/querySelector" target="_blank" rel="noopener noreferrer">MDN Web Docs - querySelector</a></li>
<li><a href="https://developer.mozilla.org/pt-BR/docs/Web/API/Element/closest" target="_blank" rel="noopener noreferrer">MDN Web Docs - Element.closest()</a></li>
<li><a href="https://javascript.info/dom-navigation" target="_blank" rel="noopener noreferrer">JavaScript.info - DOM Navigation</a></li>
<li><a href="https://web.dev/dom-size/" target="_blank" rel="noopener noreferrer">Web.dev - DOM Performance</a></li>
</ul>