Nós do DOM em JavaScript
Entenda os nós do DOM: o Document Object Model é a interface entre documentos HTML e JavaScript para criar páginas web interativas.
Entendendo os Nós do DOM
O Document Object Model (DOM) é um conceito fundamental no desenvolvimento web, atuando como a interface entre documentos HTML e JavaScript. Quando uma página web é carregada, o navegador analisa o HTML e constrói o DOM — uma árvore de objetos em memória, mantida viva, que o JavaScript pode ler e modificar. Cada alteração feita no DOM é refletida na página instantaneamente, o que torna possíveis as aplicações web interativas.
Este guia aborda os nós do DOM: o que são, os diferentes tipos que você encontrará, como identificá-los e como criar, adicionar, remover e substituí-los. Ao final, você entenderá os blocos de construção nos quais toda técnica DOM de nível superior — como selecionar elementos ou percorrer a árvore — é baseada.
O que é um Nó do DOM?
Um nó é a unidade mais básica da árvore do DOM. Tudo em um documento — elementos, o texto dentro deles, atributos e até comentários — é representado como um nó. Cada nó é um object que herda da classe Node integrada, portanto todos compartilham um conjunto comum de propriedades (nodeType, nodeName, parentNode, childNodes, e assim por diante) usadas para navegação e manipulação.
Uma maneira útil de visualizar: o HTML que você escreve é a receita, e o DOM é o objeto vivo que o navegador prepara a partir dessa receita. Depois que a página é carregada, você não edita mais o texto HTML — você edita os nós.
<!DOCTYPE html>
<html>
<head>
<title>DOM Nodes Example</title>
</head>
<body>
<div id="example">
<!-- This is a comment node -->
<p>This is a text node within an element node.</p>
</div>
<script>
let exampleDiv = document.getElementById('example');
exampleDiv.style.border = '2px solid blue'; // Highlight the div element
exampleDiv.style.padding = '10px';
</script>
</body>
</html>Explicação: Neste exemplo, acessamos o div com o ID example e aplicamos estilos CSS para distingui-lo visualmente. Isso demonstra como manipular diretamente as propriedades de estilo de um nó de elemento, tornando-o mais perceptível na página.
Os Diferentes Tipos de Nós do DOM
Cada nó possui uma propriedade numérica nodeType que informa que tipo de nó ele é. Os tipos mais comuns com os quais você trabalhará são:
nodeType | Constante | Significado |
|---|---|---|
1 | Node.ELEMENT_NODE | Um elemento HTML como <div> ou <p> |
3 | Node.TEXT_NODE | O texto dentro de um elemento (incluindo espaços em branco) |
8 | Node.COMMENT_NODE | Um comentário HTML (<!-- ... -->) |
9 | Node.DOCUMENT_NODE | O próprio object document, a raiz da árvore |
Uma surpresa comum para iniciantes: espaços em branco contam como nós de texto. As quebras de linha e a indentação entre suas tags criam nós de texto vazios, razão pela qual childNodes frequentemente retorna mais itens do que o esperado. (Se você quiser apenas os filhos que são elementos e pular esses nós de texto de espaço em branco, use children em vez de childNodes.) Os atributos também são nós, mas o código moderno os lê com getAttribute() / setAttribute() em vez de percorrer os nós de atributo diretamente.
O exemplo abaixo percorre os nós filhos de um <div> e reporta o tipo de cada um:
<!DOCTYPE html>
<html>
<head>
<title>Node Types Interactive Example</title>
<style>
#info {
border: 1px solid #ccc;
padding: 10px;
margin-bottom: 10px;
}
#output {
border: 1px solid #ccc;
padding: 10px;
}
button {
cursor: pointer;
margin-bottom: 10px;
}
</style>
</head>
<body>
<div id="info">
<!-- This is a comment node -->
<p>Element node with a <span>child element node</span> and some text.</p>
</div>
<button onclick="displayNodeTypes()">Show Node Types</button>
<div id="output">Node types will be displayed here.</div>
<script>
function displayNodeTypes() {
const infoDiv = document.getElementById('info');
const outputDiv = document.getElementById('output');
outputDiv.innerHTML = ''; // Clear previous output
const nodeTypes = [];
// Iterate over all child nodes of the div
infoDiv.childNodes.forEach(node => {
let typeDescription = '';
switch(node.nodeType) {
case Node.ELEMENT_NODE:
typeDescription = 'Element node: ' + node.tagName;
break;
case Node.TEXT_NODE:
// Trim text content and check if it's not empty
let textContent = node.textContent.trim();
if (textContent) {
typeDescription = 'Text node: "' + textContent + '"';
}
break;
case Node.COMMENT_NODE:
typeDescription = 'Comment node: "' + node.textContent.trim() + '"';
break;
}
// Only add non-empty descriptions
if (typeDescription) {
nodeTypes.push(typeDescription);
const p = document.createElement('p');
p.textContent = typeDescription;
outputDiv.appendChild(p);
}
});
// If no nodes are visible or found
if (nodeTypes.length === 0) {
outputDiv.textContent = 'No visible nodes found.';
}
}
</script>
</body>
</html>O documento HTML demonstra como identificar e exibir diferentes tipos de nós do DOM (como nós de elemento, texto e comentário). Ele inclui uma seção estilizada para mostrar esses nós, um botão que aciona uma função JavaScript para analisar e listar esses nós, e uma área para exibir os resultados. A função JavaScript inspeciona cada nó dentro de uma parte designada do documento, categoriza-o e exibe seu tipo e detalhes.
Manipulando Nós do DOM
Páginas interativas são construídas modificando nós depois que a página foi carregada. As quatro operações mais usadas são criar, adicionar, remover e substituir nós. Para uma visão mais ampla das técnicas construídas sobre essas operações, veja manipulação do DOM.
Criando e Adicionando Nós
Criar um nó e adicioná-lo são dois passos separados. document.createElement() cria um nó desconectado que ainda não está na página; appendChild() (ou append(), prepend(), insertBefore()) é o que efetivamente o insere na árvore:
<!DOCTYPE html>
<html>
<head>
<title>Add Node Example</title>
</head>
<body>
<button onclick="addNewParagraph()">Add Paragraph</button>
<script>
function addNewParagraph() {
let newNode = document.createElement('p');
newNode.textContent = 'This is a new paragraph.';
document.body.appendChild(newNode);
}
</script>
</body>
</html>Explicação: Este exemplo inclui um botão que, quando clicado, aciona uma função para criar um novo elemento de parágrafo (<p>) e o acrescenta ao corpo do documento. Demonstra como o JavaScript pode ser usado para adicionar conteúdo dinamicamente a uma página, o que é particularmente útil para aplicações que precisam se atualizar em tempo real sem recarregar a página.
Removendo Nós
Para remover um nó da página, chame removeChild() em seu pai, ou — de forma mais simples nos navegadores modernos — chame node.remove() diretamente no próprio nó. O exemplo usa removeChild() para que você possa ver explicitamente a relação pai/filho:
<!DOCTYPE html>
<html>
<head>
<title>Remove Node Example</title>
</head>
<body>
<div id="container">
<p id="toBeRemoved">This paragraph will be removed. <button onclick="removeParagraph()">Remove</button></p>
</div>
<script>
function removeParagraph() {
let parentNode = document.getElementById('container');
let childNode = document.getElementById('toBeRemoved');
parentNode.removeChild(childNode);
}
</script>
</body>
</html>Explicação: Este script fornece uma demonstração prática de como remover um elemento do DOM usando um botão incorporado no próprio parágrafo. O método removeChild() é usado para remover o elemento especificado, apresentando uma ação dinâmica iniciada pelo usuário que altera a estrutura do documento diretamente.
Substituindo Nós
replaceChild(newNode, oldNode) troca um nó por outro em uma única etapa, preservando a posição do nó antigo na árvore:
<!DOCTYPE html>
<html>
<head>
<title>Replace Node Example</title>
</head>
<body>
<div id="oldElement">This element will be replaced. <button onclick="replaceElement()">Replace</button></div>
<script>
function replaceElement() {
let newNode = document.createElement('div');
newNode.textContent = 'This is a replacement.';
let oldNode = document.getElementById('oldElement');
oldNode.parentNode.replaceChild(newNode, oldNode);
}
</script>
</body>
</html>Explicação: Neste exemplo interativo, um botão aciona a substituição de um div existente por um div recém-criado. Isso ilustra o método replaceChild(), que é particularmente útil em situações onde um elemento precisa ser atualizado com base em ações do usuário ou eventos externos, como o recebimento de novos dados de um servidor.
Boas Práticas e Dicas
- Minimize as manipulações do DOM: Cada alteração pode fazer o navegador recalcular o layout (um reflow) e redesenhar a página (um repaint). Agrupe suas alterações em vez de tocar no DOM em um loop intenso.
- Leia, depois escreva: Misturar leituras (como
offsetHeight) e escritas dentro de um loop força repetições de layout thrashing. Agrupe todas as suas leituras juntas e todas as suas escritas juntas. - Monte fora da tela, insira de uma vez: Use um
DocumentFragment(mostrado abaixo) para montar muitos elementos antes de inseri-los em uma única operação. - Armazene suas seleções em cache: Guarde os resultados de
getElementById/querySelectorem uma variável em vez de re-consultar o mesmo elemento repetidamente. Veja otimização de desempenho do DOM para mais detalhes.
Sempre garanta a compatibilidade entre navegadores ao realizar manipulações do DOM. Testar em diferentes navegadores ajuda a prevenir comportamentos inesperados e garante uma experiência de usuário consistente.
Exemplo com DocumentFragment
Um DocumentFragment é um contêiner leve e fora da tela para nós. Como não faz parte do documento vivo, acrescentar nós a ele não tem custo em layout — o navegador só reprocessa uma vez, quando você insere o fragmento inteiro na página. Isso o torna ideal para adicionar muitos elementos de uma vez:
<!DOCTYPE html>
<html>
<head>
<title>DocumentFragment Example</title>
</head>
<body>
<div id="list-container">
<h2>Item List</h2>
<ul id="item-list">
<!-- Items will be added here -->
</ul>
<button id="add-items">Add 100 Items</button>
</div>
<script>
const itemList = document.getElementById('item-list');
const addItemsButton = document.getElementById('add-items');
addItemsButton.addEventListener('click', () => {
// Create a DocumentFragment
const fragment = document.createDocumentFragment();
// Add 100 list items to the fragment
for (let i = 1; i <= 100; i++) {
const listItem = document.createElement('li');
listItem.textContent = `Item ${i}`;
fragment.appendChild(listItem);
}
// Append the fragment to the item list
itemList.appendChild(fragment);
});
</script>
</body>
</html>- Começamos selecionando o elemento
<ul>onde os novos itens serão adicionados e o botão que acionará a adição. - Quando o botão "Add 100 Items" é clicado, criamos um object
DocumentFragment. - Em seguida, criamos 100 elementos
<li>em um loop, definimos seu conteúdo de texto e acrescentamos cada um aoDocumentFragment. - Por fim, acrescentamos o
DocumentFragmentao elemento<ul>. Como o fragmento não faz parte do DOM vivo durante a fase de construção, essa abordagem minimiza os reflows e repaints, melhorando o desempenho.
Usar DocumentFragment é particularmente útil quando você precisa adicionar um grande número de elementos ao DOM de uma só vez, pois reduz a sobrecarga associada a múltiplos reflows e repaints, resultando em atualizações mais suaves e rápidas.
Nós do DOM vs. árvores do DOM
Nós do DOM e árvores do DOM são conceitos relacionados, mas se referem a aspectos diferentes de como um documento web é estruturado e manipulado:
- Nós do DOM: Um nó do DOM é um componente individual dentro do Document Object Model (DOM). Todo elemento, texto, comentário e atributo dentro de um documento HTML ou XML é considerado um nó. Os nós são os blocos de construção fundamentais de um documento. Por exemplo, uma tag
<h1>, o texto dentro dessa tag e até os atributos dessa tag (comoclass="title") são todos nós separados. - Árvore do DOM: A árvore do DOM se refere a toda a estrutura ou hierarquia de nós conforme estão organizados no documento. É uma representação em forma de árvore que mostra como todos os nós de um documento estão relacionados entre si. Os nós nessa árvore têm relacionamentos de pai e filho, assim como pastas e arquivos no seu computador. Por exemplo, em um documento HTML, o nó
<body>pode ser um nó pai, com vários nós filhos como<div>,<p>e<img>que representam diferentes partes da página web.
Em termos simples, você pode pensar em um nó do DOM como um único ponto ou uma peça de um quebra-cabeça maior, enquanto a árvore do DOM representa o quebra-cabeça completo ou o conjunto total de relacionamentos entre esses pontos. A árvore do DOM é útil para navegar e manipular a estrutura de um documento por meio de linguagens de programação como JavaScript, pois permite aos desenvolvedores encontrar (selecionar), modificar ou atualizar elementos de forma eficiente dentro da hierarquia aninhada.
Conclusão
Os nós são os átomos do DOM. Quando você consegue reconhecer os diferentes tipos de nós, ler o nodeType de um nó e criar, adicionar, remover e substituir nós com confiança, toda tarefa DOM de nível superior se torna acessível. Tenha o desempenho em mente — agrupe suas alterações e recorra a um DocumentFragment ao inserir muitos elementos de uma vez.
O que ler a seguir
- Propriedades de nós: tipo, tag e conteúdos — aprofunde-se em
nodeType,nodeName,textContente afins. - Selecionando elementos do DOM — encontre os nós com os quais deseja trabalhar.
- Percorrendo o DOM — mova-se entre nós pai, filho e irmãos.
- Manipulação do DOM — um kit de ferramentas mais completo construído sobre as operações abordadas aqui.