O Document Object Model (DOM) é a interface programática que representa documentos HTML e XML como uma árvore hierárquica de objetos. Essa estrutura permite que scripts interajam dinamicamente com o conteúdo, estilo e comportamento da página.
Estrutura de Nós
Todos os elementos do DOM herdam da interface base Node. Cada nó possui um tipo identificado numericamente:
Node.ELEMENT_NODE(valor1) — para elementos como<div>,<p>Node.TEXT_NODE(valor3) — conteúdo textual entre tagsNode.COMMENT_NODE(valor8) — comentários HTMLNode.DOCUMENT_NODE(valor9) — raiz do documento (document)
Propriedades comuns incluem parentNode, childNodes (coleção ao vivo do tipo NodeList), nextSibling, previousSibling, além de nodeName e nodeValue, cujo uso varia conforme o tipo de nó.
O Objeto document
A instância principal do DOM no navegador é o objeto document, tipicamente uma HTMLDocument. Ele oferece acesso direto a partes críticas da página:
const htmlRoot = document.documentElement; // <html>
const mainBody = document.body; // <body>
const pageTitle = document.title; // título da aba
Para seleção de elementos, as APIs modernas priorizam métodos baseados em seletores CSS:
document.querySelector('button.primary')— retorna o primeiro elemento correspondente ounulldocument.querySelectorAll('nav a')— retorna umaNodeListestática (não atualizada automaticamente)
Em contraste, métodos legados como getElementsByTagName retornam coleções dinâmicas (HTMLCollection), o que pode impactar desempenho em loops intensivos.
Manipulação de Elementos
Elementos individuais são representados pela interface Element. Acessar e modificar atributos segue duas vias:
const btn = document.querySelector('button');
// Atributos padrão: acesso direto via propriedade
btn.id = 'submit-btn';
btn.className = 'btn btn-success';
// Atributos personalizados: use dataset ou getAttribute
btn.dataset.userId = '42'; // cria data-user-id="42"
console.log(btn.getAttribute('data-role')); // "admin"
Para inserção eficiente de múltiplos nós, recomenda-se usar DocumentFragment:
const fragment = document.createDocumentFragment();
for (let i = 0; i < 5; i++) {
const item = document.createElement('li');
item.textContent = `Item ${i + 1}`;
fragment.appendChild(item);
}
document.querySelector('ul').appendChild(fragment); // uma única operação no DOM
Estilos e Layout
O acesso a estilos ocorre em dois níveis:
- Estilo inline: via propriedade
style, usando notação camelCase (element.style.backgroundColor) - Estilo computado: via
getComputedStyle(element), que retorna um objeto somente leitura com valores finais aplicados (incluindo regras de folhas de estilo externas)
APIs Modernas para Navegação e Interação
As interfaces children, firstElementChild e nextElementSibling ignoram nós de texto e comentários — útil para iterações sem tratamento extra:
const container = document.getElementById('grid');
for (let child = container.firstElementChild; child; child = child.nextElementSibling) {
child.classList.add('animated');
}
O método scrollIntoView() suporta opções avançadas:
element.scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'nearest'
});
Segurança e Desempenho
Operações como innerHTML exigem cautela: nunca insira conteúdo não sanitizado proveniente de usuários. Substitua por textContent quando o objetivo for apenas exibir texto. Para renderização segura de HTML dinâmico, considere bibliotecas especializadas ou funções de escape manuais.
A otimização de desempenho envolve evitar "layout thrashing": leituras e escritas alternadas de propriedades geométricas (como offsetHeight) forçam recalculos repetidos do layout. Agrupe leituras antes de escritas, ou utilize requestAnimationFrame para sincronziar com o ciclo de renderização.