W3docs

Técnicas de Manipulação do DOM em JavaScript

Aprenda técnicas de manipulação do DOM em JavaScript: crie, insira, substitua e remova elementos, e otimize com batching, fragmentos de documento e clonagem de nós para minimizar reflows.

A manipulação do DOM (Document Object Model) é um aspecto fundamental do desenvolvimento web que permite criar páginas dinâmicas e interativas ao modificar a estrutura, o conteúdo e o estilo do documento a partir do JavaScript. Este guia começa com as técnicas essenciais para criar, inserir, substituir e remover elementos, e depois avança para boas práticas e otimizações de desempenho — batching, fragmentos de documento e clonagem de nós — que mantêm essas alterações rápidas.

Se você ainda não selecionou um elemento, comece com seleção de elementos do DOM. Para entender a árvore que você está modificando, consulte compreendendo os nós do DOM.

Técnicas Essenciais de Manipulação

Toda alteração no DOM se enquadra em uma de quatro categorias: criar nós, inseri-los, substituí-los ou removê-los.

Criando Elementos

Use document.createElement() para construir um elemento na memória, defina seu conteúdo e atributos antes de inseri-lo na página. Um nó criado não é visível até que seja anexado ao documento.

const card = document.createElement('div');
card.className = 'card';
card.textContent = 'Hello, DOM!';
card.setAttribute('data-role', 'greeting');

console.log(card.outerHTML);
// <div class="card" data-role="greeting">Hello, DOM!</div>

Prefira textContent em vez de innerHTML ao inserir texto simples — é mais rápido e evita o risco de segurança de injeção de HTML não escapado.

Inserindo Elementos

Uma vez que o elemento existe, anexe-o com um destes métodos:

  • parent.append(node) — adiciona o nó como último filho (também aceita strings simples).
  • parent.prepend(node) — adiciona como primeiro filho.
  • target.before(node) / target.after(node) — insere um irmão antes ou depois de target.
  • parent.appendChild(node) — a API clássica; anexa um único nó e o retorna.
  • parent.insertBefore(node, reference) — insere node antes do filho reference.
const list = document.createElement('ul');

const first = document.createElement('li');
first.textContent = 'First';
list.append(first);

const second = document.createElement('li');
second.textContent = 'Second';
list.append(second);

// Put a new item before the first one.
const top = document.createElement('li');
top.textContent = 'Top';
first.before(top);

console.log(list.children.length); // 3
console.log(list.firstElementChild.textContent); // Top

Para inserir uma string HTML em uma posição precisa sem reanalisar o elemento pai inteiro, use insertAdjacentHTML():

const wrapper = document.createElement('div');
const box = document.createElement('div');
box.textContent = 'middle';
wrapper.append(box); // box must be in the tree to gain siblings

box.insertAdjacentHTML('beforebegin', '<span>before</span>');
box.insertAdjacentHTML('afterend', '<span>after</span>');

console.log(box.previousElementSibling.textContent); // before
console.log(box.nextElementSibling.textContent);     // after

Substituindo e Removendo Elementos

  • oldNode.replaceWith(newNode) — substitui oldNode por newNode no lugar.
  • element.remove() — desconecta o elemento do DOM.
  • parent.replaceChild(newNode, oldNode) e parent.removeChild(child) — os equivalentes mais antigos.
const parent = document.createElement('div');
const a = document.createElement('p');
a.textContent = 'old';
parent.append(a);

const b = document.createElement('p');
b.textContent = 'new';
a.replaceWith(b);

console.log(parent.innerHTML); // <p>new</p>

b.remove();
console.log(parent.innerHTML); // (empty)
Informação

Os métodos modernos (append, prepend, before, after, replaceWith, remove) são mais fáceis de ler do que os legados appendChild/insertBefore/replaceChild/removeChild e aceitam múltiplos nós e strings de uma só vez. Prefira-os; recorra à API legada apenas quando for necessário suportar navegadores muito antigos.

Boas Práticas de Manipulação do DOM

Minimize o Acesso Direto ao DOM

Acessar o DOM pode ser lento porque pode fazer o navegador recalcular o layout e repintar os elementos. Para minimizar o acesso direto ao DOM:

  • Agrupe as atualizações do DOM em lote em vez de realizar múltiplas atualizações pequenas.
  • Use variáveis para armazenar referências a elementos acessados com frequência.

Otimize o Tratamento de Eventos

Anexe manipuladores de eventos de forma eficiente:

  • Use delegação de eventos para reduzir o número de ouvintes de eventos.
  • Evite anexar muitos ouvintes de eventos diretamente aos elementos.

Limpe Elementos Desnecessários

Remova elementos que não são mais necessários para liberar memória e melhorar o desempenho:

  • Use os métodos removeChild ou remove para excluir elementos do DOM.

Minimizando Reflows e Repaints

O que São Reflows e Repaints?

  • Reflows ocorrem quando o layout de uma parte da página muda, fazendo o navegador recalcular as posições e tamanhos dos elementos.
  • Repaints acontecem quando a aparência visual dos elementos muda sem afetar o layout (por exemplo, mudanças de cor).

Técnicas para Minimizar Reflows e Repaints

Agrupar Alterações em Lote

Agrupe múltiplas alterações para evitar reflows e repaints repetidos:

<!DOCTYPE html>
<html>
<head>
    <title>Batching Changes</title>
</head>
<body>
    <div id="content">Original Content</div>
    <button id="update">Update Content</button>

    <script>
        document.getElementById('update').addEventListener('click', () => {
            const content = document.getElementById('content');
            content.style.display = 'none'; // Hide element to batch changes
            content.innerHTML = 'Updated Content';
            content.style.display = 'block'; // Show element after updates
        });
    </script>
</body>
</html>

Este exemplo mostra como agrupar alterações em um elemento do DOM para minimizar reflows e repaints. Ao ocultar o elemento antes de realizar múltiplas atualizações e exibi-lo novamente depois, você evita reflows e repaints intermediários.

Use Classes CSS para Alterações

Aplique alterações de CSS usando classes em vez de manipular estilos diretamente:

<!DOCTYPE html>
<html>
<head>
    <title>Use CSS Classes</title>
    <style>
        .hidden { display: none; }
        .highlight { color: red; font-weight: bold; }
    </style>
</head>
<body>
    <div id="content">Hello World</div>
    <button id="toggle">Toggle Highlight</button>

    <script>
        document.getElementById('toggle').addEventListener('click', () => {
            const content = document.getElementById('content');
            content.classList.toggle('highlight');
        });
    </script>
</body>
</html>

Este exemplo demonstra como usar classes CSS para aplicar múltiplas alterações de estilo de uma só vez, o que é mais eficiente do que modificar propriedades de estilo individualmente. Alternar uma classe que muda múltiplos estilos ajuda a reduzir o número de reflows e repaints.

Usando Fragmentos de Documento para Desempenho

O que É um Fragmento de Documento?

Um Fragmento de Documento é um contêiner leve usado para armazenar um grupo de nós. Ele não faz parte da árvore principal do DOM, o que significa que as alterações nele não acionam reflows e repaints.

Informação

Ao realizar múltiplas manipulações no DOM, use DocumentFragment para agrupar suas alterações e anexá-las ao DOM em uma única operação. Essa abordagem minimiza reflows e repaints, melhorando significativamente o desempenho.

Exemplo de Uso de Fragmentos de Documento

<!DOCTYPE html>
<html>
<head>
    <title>Document Fragments</title>
</head>
<body>
    <div id="list"></div>
    <button id="populate">Populate List</button>

    <script>
        document.getElementById('populate').addEventListener('click', (event) => {
            const fragment = document.createDocumentFragment();
            for (let i = 1; i <= 25; i++) {
                const item = document.createElement('div');
                item.textContent = `Item ${i}`;
                fragment.appendChild(item);
            }
            document.getElementById('list').appendChild(fragment);
            event.target.disabled = true; // Disable the button
        });
    </script>
</body>
</html>

Este exemplo cria 25 elementos div e os adiciona a um Fragmento de Documento. Somente após todos os elementos serem adicionados ao fragmento, o fragmento é inserido no DOM em uma única operação. Essa abordagem minimiza reflows e repaints ao atualizar o DOM apenas uma vez.

Clonando Nós

O Método cloneNode()

O método cloneNode() é usado para criar uma cópia de um nó. Ele pode clonar o próprio nó ou o nó junto com seus filhos.

Clonando um Nó Sem Filhos

<!DOCTYPE html>
<html>
<head>
    <title>Cloning Nodes</title>
</head>
<body>
    <div id="original">Original Node</div>
    <button id="clone">Clone Node</button>

    <script>
        document.getElementById('clone').addEventListener('click', () => {
            const original = document.getElementById('original');
            const clone = original.cloneNode(false); // Clone without children
            clone.id = 'clone';
            clone.textContent = 'Cloned Node';
            document.body.appendChild(clone);
        });
    </script>
</body>
</html>

Este exemplo demonstra como clonar um nó sem seus filhos usando o método cloneNode(false). O nó clonado copiará os atributos e o conteúdo de texto do nó original, mas não seus nós filhos.

Clonando um Nó Com Filhos

<!DOCTYPE html>
<html>
<head>
    <title>Cloning Nodes with Children</title>
</head>
<body>
    <div id="original">
        Original Node
        <span>Child Node</span>
    </div>
    <button id="clone">Clone Node with Children</button>

    <script>
        document.getElementById('clone').addEventListener('click', () => {
            const original = document.getElementById('original');
            const clone = original.cloneNode(true); // Clone with children
            clone.id = 'clone';
            document.body.appendChild(clone);
        });
    </script>
</body>
</html>

Este exemplo demonstra como clonar um nó junto com seus filhos usando o método cloneNode(true). O nó clonado incluirá o conteúdo do nó original e todos os seus nós descendentes.

Conclusão

A manipulação eficiente do DOM é fundamental para criar aplicações web com bom desempenho. Comece dominando os métodos essenciais para criar, inserir, substituir e remover elementos, e depois adicione as otimizações: agrupe suas atualizações em lote, prefira classes CSS a estilos inline, use DocumentFragment para inserções em massa e clone nós quando precisar de estruturas repetidas. Em conjunto, essas técnicas mantêm suas páginas responsivas mesmo conforme o DOM cresce.

Tópicos Relacionados

Prática

Prática
Quais dos seguintes métodos são usados para manipular o DOM em JavaScript?
Quais dos seguintes métodos são usados para manipular o DOM em JavaScript?
Was this page helpful?