A manipulação do DOM (Document Object Model) é uma habilidade essencial para qualquer desenvolvedor front-end. O DOM é uma representação em árvore do documento HTML, e o JavaScript nos permite acessar, modificar, adicionar ou remover elementos dinamicamente. Nesta aula, vamos explorar quatro aspectos fundamentais: a diferença entre textContent e innerHTML, como trabalhar com atributos, como alterar estilos e como criar e remover elementos. Cada tópico será acompanhado de exemplos práticos para que você possa aplicar imediatamente.

Antes de começar, lembre-se de que todo código JavaScript de manipulação do DOM deve ser executado após o carregamento do documento, geralmente usando o evento DOMContentLoaded ou colocando os scripts no final do body. Vamos supor que temos um HTML básico com uma div de id app e alguns elementos para testar.

textContent vs innerHTML

Ambas as propriedades permitem obter ou definir o conteúdo textual de um elemento, mas com diferenças importantes. textContent retorna o texto puro, ignorando qualquer formatação HTML, enquanto innerHTML retorna o conteúdo incluindo as tags HTML, e também permite inserir HTML novo. Usar innerHTML para inserir conteúdo pode ser um risco de segurança (XSS) se o conteúdo não for sanitizado.

Exemplo: considere um parágrafo com o texto "Olá Mundo!". textContent retornará "Olá Mundo!" (sem negrito), enquanto innerHTML retornará "Olá Mundo!". Ao definir innerHTML, você pode inserir tags HTML; com textContent, as tags são escapadas e exibidas como texto.

// Suponha que temos <p id="exemplo">Olá <strong>Mundo</strong>!</p>
const p = document.getElementById('exemplo');
console.log(p.textContent);  // "Olá Mundo!"
console.log(p.innerHTML);    // "Olá <strong>Mundo</strong>!"

// Definindo conteúdo
p.textContent = 'Novo <strong>texto</strong>';  // O texto aparece literalmente: <strong>texto</strong>
p.innerHTML = 'Novo <strong>texto</strong>';   // O texto aparece em negrito: Novo texto

Atributos

Atributos HTML como id, class, src, href podem ser acessados e modificados via JavaScript. Existem dois métodos principais: getAttribute e setAttribute, e também propriedades diretas como id, className, href. Para atributos booleanos como disabled, checked, use hasAttribute, setAttribute (com string vazia) ou propriedades booleanas.

Exemplo: modificar o src de uma imagem e adicionar um atributo data-* personalizado.

const img = document.querySelector('img');
console.log(img.getAttribute('src'));  // URL atual
img.setAttribute('src', 'nova-imagem.jpg');
img.setAttribute('data-info', 'exemplo');

// Propriedades diretas
img.id = 'minha-imagem';
img.className = 'foto destaque';  // substitui todas as classes
img.classList.add('borda');       // adiciona classe sem remover as existentes

Estilos

A propriedade style de um elemento permite modificar estilos CSS inline. Cada propriedade CSS é acessada como uma propriedade em camelCase (ex.: backgroundColor para background-color). Para obter estilos computados (incluindo de folhas de estilo), use getComputedStyle.

Exemplo: alterar cor de fundo e tamanho da fonte de um elemento.

const div = document.getElementById('app');
div.style.backgroundColor = 'lightblue';
div.style.fontSize = '20px';
div.style.border = '2px solid black';

// Obter estilo computado
const computed = getComputedStyle(div);
console.log(computed.backgroundColor);  // rgb(173, 216, 230) ou similar

Criar/remover elementos

Para criar novos elementos, use document.createElement, configure suas propriedades e insira no DOM com appendChild, insertBefore, append, prepend etc. Para remover, use removeChild ou o método remove diretamente no elemento.

Exemplo: criar uma lista não ordenada e adicionar itens dinamicamente.

// Criar elementos
const ul = document.createElement('ul');
const li1 = document.createElement('li');
li1.textContent = 'Item 1';
const li2 = document.createElement('li');
li2.textContent = 'Item 2';

// Inserir na árvore
ul.appendChild(li1);
ul.appendChild(li2);
document.body.appendChild(ul);

// Remover o primeiro item
ul.removeChild(li1);  // ou li1.remove()

Boas Práticas

Ao manipular o DOM, prefira textContent a innerHTML para evitar riscos de XSS. Use classList para manipular classes em vez de className para não sobrescrever classes existentes. Para estilos, evite modificar style diretamente em loops; prefira adicionar/remover classes CSS. Sempre que possível, faça alterações em lote (usando fragmentos de documento) para minimizar reflows.

Referências

Exercícios

  1. Dado um elemento <p id="texto">Olá <em>mundo</em>!</p>, escreva código que exiba no console o texto sem formatação e o HTML interno.

    ✓ Resposta:
    const p = document.getElementById('texto');
    console.log(p.textContent);  // "Olá mundo!"
    console.log(p.innerHTML);    // "Olá <em>mundo</em>!"
    
  2. Selecione uma imagem e altere seu atributo src para https://via.placeholder.com/150 e adicione um atributo alt com texto "Placeholder".

    ✓ Resposta:
    const img = document.querySelector('img');
    img.setAttribute('src', 'https://via.placeholder.com/150');
    img.setAttribute('alt', 'Placeholder');
    
  3. Altere o estilo de um elemento com id destaque para ter cor de texto vermelha e tamanho de fonte 24px.

    ✓ Resposta:
    const el = document.getElementById('destaque');
    el.style.color = 'red';
    el.style.fontSize = '24px';
    
  4. Crie um parágrafo com o texto "Este é um novo parágrafo" e insira-o como o primeiro filho do body.

    ✓ Resposta:
    const p = document.createElement('p');
    p.textContent = 'Este é um novo parágrafo';
    document.body.prepend(p);  // ou document.body.insertBefore(p, document.body.firstChild);
    
  5. Remova o último filho de um elemento com id lista.

    ✓ Resposta:
    const lista = document.getElementById('lista');
    const ultimoFilho = lista.lastElementChild;
    if (ultimoFilho) {
      lista.removeChild(ultimoFilho);  // ou ultimoFilho.remove();
    }