O DOM — a árvore do documento
O browser transforma seu HTML em uma árvore de objetos em memória — o DOM. É por aqui que o JavaScript lê e modifica a página.
HTML é texto; DOM é uma árvore de objetos
Quando o browser recebe o HTML, ele não o exibe diretamente — ele o parseia e constrói
uma árvore de objetos em memória chamada DOM (Document Object Model).
Cada tag HTML vira um Node. Tags viram Element. Textos viram
Text. Comentários viram Comment.
Essa árvore é o que o JavaScript manipula. Quando você escreve
document.querySelector("h1").textContent = "Novo título",
você está mudando um nodo na árvore DOM — e o browser re-renderiza apenas o que mudou.
Explore a árvore DOM
Edite o HTML à esquerda e veja a árvore DOM atualizar em tempo real. Clique nos nodos para inspecionar atributos.
Manipulando o DOM com JavaScript
// Acessar e manipular o DOM com JavaScript // Seleção — encontrar elementos document.getElementById("btn") // por id (único) document.querySelector(".intro") // primeiro elemento que bate com o seletor CSS document.querySelectorAll("li") // NodeList com todos os <li> // Leitura e escrita de conteúdo const el = document.querySelector("h1"); el.textContent // texto puro (sem HTML) el.innerHTML // HTML interno (XSS risco — sanitize inputs!) el.setAttribute("id", "novo") // define atributo el.classList.add("ativo") // adiciona classe CSS el.style.color = "red" // estilo inline (evite — prefira classList) // Criar e inserir elementos const li = document.createElement("li"); li.textContent = "Novo item"; document.querySelector("ul").appendChild(li); // Remover el.remove(); // remove o próprio elemento
Eventos e interatividade
// Eventos — reagir a ações do usuário document.querySelector("#btn").addEventListener("click", (e) => { console.log("Clicou!", e.target); // e.target = elemento clicado }); // Event delegation — um listener para vários filhos document.querySelector("ul").addEventListener("click", (e) => { if (e.target.tagName === "LI") { console.log("Li clicado:", e.target.textContent); } }); // Event bubbling: click em filho sobe até o document // stopPropagation() para parar
textContent para textos simples
(mais seguro, mais rápido). Use innerHTML só quando precisar inserir HTML real —
e nunca com dados do usuário sem sanitizar, pois é um vetor de XSS.
O método moderno e seguro é el.insertAdjacentHTML("beforeend", html)
com uma biblioteca de sanitização.
Construa um DOM Inspector
Mini projeto: escreva uma função printTree(el, depth) que imprime no console a árvore DOM a partir de um elemento, com indentação por nível. Use recursão e el.children.
Projeto principal: crie uma extensão de browser simples (manifest.json + content script) que ao clicar em qualquer elemento da página mostra um tooltip com o seletor CSS único daquele elemento (el.tagName + "#" + el.id + "." + el.className).
Desafio extra: implemente o algoritmo de diff do Virtual DOM: dadas duas árvores (objetos JS), produza uma lista de operações mínimas (insert, remove, update) para transformar uma na outra. É assim que React e Vue funcionam internamente.
Teste sua intuição
<li>, o evento também dispara no <ul> pai e no <body>. Isso é...
Onde você encontra isso
React e Vue
Frameworks modernos não manipulam o DOM diretamente — usam um Virtual DOM (árvore JS) para calcular o diff mínimo e aplicar apenas as mudanças necessárias, evitando reflows desnecessários.
DevTools Inspector
O painel "Elements" do Chrome DevTools é uma visualização do DOM ao vivo. Você pode editar atributos, textos e estilos diretamente — ideal para depurar e experimentar sem alterar o código.
Acessibilidade
Leitores de tela como NVDA e VoiceOver leem a árvore DOM (e o ARIA tree por cima dela). Estrutura semântica correta (<nav>, <main>, role=) é essencial para acessibilidade.
Testes E2E
Playwright e Cypress localizam elementos pelo DOM: page.getByRole("button"), cy.get("[data-testid='login']"). Testes que dependem de texto e roles são mais robustos que seletores CSS frágeis.