O DOM (Document Object Model) é uma interface de programação que representa documentos HTML e XML como uma estrutura de árvore de nós, permitindo que linguagens como JavaScript acessem e modifiquem o conteúdo, a estrutura e o estilo de uma página web dinamicamente. Com o DOM, você pode criar páginas interativas, responder a eventos do usuário e atualizar partes da página sem recarregá-la.

Nesta aula, vamos entender o que é o DOM, como ele organiza os elementos em uma árvore de nós e como o objeto document serve como ponto de entrada para manipular a página.

O que é o DOM

O DOM é uma representação em memória de um documento HTML ou XML. O navegador, ao carregar uma página, constrói essa representação em forma de árvore hierárquica, onde cada elemento HTML, atributo e texto se torna um nó. JavaScript pode interagir com o DOM para alterar elementos, adicionar ou remover nós, modificar estilos e muito mais.

Por exemplo, ao clicar em um botão, você pode usar o DOM para alterar o texto de um parágrafo. Isso é feito acessando o nó do parágrafo e alterando sua propriedade textContent.

// Exemplo: alterar o texto de um parágrafo com id "demo"
const paragrafo = document.getElementById('demo');
paragrafo.textContent = 'Novo texto!';

O DOM não é parte da linguagem JavaScript, mas sim uma API fornecida pelo ambiente do navegador. Ele é padronizado pelo W3C (World Wide Web Consortium) e é independente de linguagem, embora seja mais comumente usado com JavaScript.

A árvore de nós

O DOM organiza o documento em uma estrutura de árvore, chamada de "árvore de nós". Cada nó representa uma parte do documento: elementos, texto, atributos, comentários etc. O nó raiz é o document, que contém o nó html, que por sua vez contém head e body, e assim por diante.

Existem vários tipos de nós, mas os mais comuns são:

  • Nó de elemento (nodeType 1): representa tags HTML como <div>, <p>, etc.
  • Nó de texto (nodeType 3): contém o texto dentro de um elemento.
  • Nó de atributo (nodeType 2): representa atributos de elementos, mas é menos usado diretamente.
  • Nó de comentário (nodeType 8): comentários HTML.

Cada nó possui propriedades como parentNode, childNodes, firstChild, lastChild, nextSibling e previousSibling, que permitem navegar pela árvore.

// Navegando pela árvore de nós
const body = document.body;
const firstChild = body.firstChild; // pode ser um nó de texto (espaço) ou elemento
console.log(firstChild.nodeType); // 3 se for texto, 1 se for elemento

É importante lembrar que espaços em branco e quebras de linha entre tags também são considerados nós de texto, o que pode causar confusão. Por isso, muitos métodos como children (que retorna apenas elementos) são preferíveis a childNodes.

document

O objeto document é a raiz do DOM e fornece métodos e propriedades para acessar e manipular a página. Ele é uma propriedade do objeto global window no navegador.

Principais métodos e propriedades:

  • document.getElementById(id): retorna o elemento com o ID especificado.
  • document.getElementsByTagName(tag): retorna uma coleção de elementos com a tag especificada.
  • document.getElementsByClassName(class): retorna uma coleção de elementos com a classe especificada.
  • document.querySelector(selector): retorna o primeiro elemento que corresponde ao seletor CSS.
  • document.querySelectorAll(selector): retorna uma NodeList com todos os elementos que correspondem ao seletor.
  • document.createElement(tag): cria um novo elemento HTML.
  • document.createTextNode(text): cria um nó de texto.

Exemplo de uso:

// Acessando elementos
const titulo = document.querySelector('h1');
titulo.style.color = 'red';

// Criando e inserindo elementos
const novoParagrafo = document.createElement('p');
const texto = document.createTextNode('Este é um novo parágrafo.');
novoParagrafo.appendChild(texto);
document.body.appendChild(novoParagrafo);

O objeto document também possui propriedades como document.title, document.URL, document.body, document.head, entre outras.

Boas práticas

Ao trabalhar com o DOM, prefira usar querySelector e querySelectorAll por serem mais flexíveis e consistentes. Evite manipular o DOM excessivamente em loops, pois isso pode afetar a performance; em vez disso, faça alterações em lote ou use fragmentos de documento (DocumentFragment). Além disso, sempre verifique se um elemento existe antes de manipulá-lo para evitar erros.

Referências

Exercícios

  1. Escreva um código que selecione o elemento com id "meu-id" e altere seu conteúdo para "Olá, DOM!".

    ✓ Resposta:
    const elemento = document.getElementById('meu-id');
    elemento.textContent = 'Olá, DOM!';
  2. Como você acessaria o primeiro elemento <li> de uma lista não ordenada com classe "lista"?

    ✓ Resposta:
    const primeiroLi = document.querySelector('ul.lista li');
    // ou
    const lista = document.querySelector('ul.lista');
    const primeiroLi = lista.querySelector('li');
  3. Crie um novo parágrafo com o texto "Este é um parágrafo criado dinamicamente" e insira-o no final do body.

    ✓ Resposta:
    const novoParagrafo = document.createElement('p');
    const texto = document.createTextNode('Este é um parágrafo criado dinamicamente');
    novoParagrafo.appendChild(texto);
    document.body.appendChild(novoParagrafo);
  4. Qual a diferença entre childNodes e children? Dê um exemplo de uso.

    ✓ Resposta:

    childNodes retorna uma NodeList de todos os nós filhos (incluindo texto, comentários etc.), enquanto children retorna uma HTMLCollection apenas dos elementos filhos (nós de elemento). Exemplo:

    const div = document.querySelector('div');
    console.log(div.childNodes); // NodeList com todos os nós
    console.log(div.children);    // HTMLCollection apenas com elementos
  5. Como você alteraria a cor de fundo de todos os parágrafos de uma página para amarelo usando JavaScript?

    ✓ Resposta:
    const paragrafos = document.querySelectorAll('p');
    paragrafos.forEach(p => {
      p.style.backgroundColor = 'yellow';
    });