Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Aula 07 - Programação Cliente (Manipulação do DOM)

Bibliografia recomendada

DOM (Document Object Model)

O DOM (Document Object Model) é uma interface de programação padronizada pelo W3C que representa o documento HTML como uma árvore de objetos (nós). Esta API permite que a linguagem JavaScript acesse, altere, adicione ou remova elementos e estilos do documento renderizado pelo navegador em tempo de execução.

Através do DOM, a estrutura estática do HTML torna-se dinâmica. O ponto de entrada principal para esta API é o objeto global document.

Manipulação do DOM

A implementação nativa da API nos navegadores modernos dispensa o uso de bibliotecas de terceiros (como jQuery) para a maioria das tarefas de manipulação.

Seleção de Elementos (Busca)

Historicamente, utilizavam-se métodos específicos para ID, classes ou tags. No JavaScript moderno, o padrão da indústria é a utilização dos métodos querySelector e querySelectorAll, que aceitam a sintaxe padrão de seletores CSS, conferindo maior flexibilidade.

// Métodos legados (ainda válidos e performáticos, mas menos flexíveis)
const porId = document.getElementById("teste");
const porClasse = document.getElementsByClassName("intro");
const porTag = document.getElementsByTagName("p");

// O padrão moderno e mais versátil: querySelector (Retorna o primeiro elemento que casar com o seletor)
const titulo = document.querySelector("#teste");
const primeiroParagrafoIntro = document.querySelector("p.intro");

// querySelectorAll (Retorna uma NodeList com todos os elementos que casam com o seletor)
const todosParagrafos = document.querySelectorAll("p");

Alteração de Conteúdo e Propriedades

Após selecionar o elemento, suas propriedades podem ser alteradas. O uso de var é obsoleto; utilize const para referências de elementos do DOM.

const elemento = document.querySelector("#p1");

// 1. textContent: Altera apenas o texto. É mais rápido e seguro contra ataques XSS.
elemento.textContent = "Novo conteúdo textual puro!";

// 2. innerHTML: Interpreta tags HTML. Use apenas se for estritamente necessário renderizar novas tags.
elemento.innerHTML = "Texto com <strong>negrito</strong>.";

// 3. Alteração de atributos
const imagem = document.querySelector("#myImage");
imagem.src = "landscape.jpg";
imagem.alt = "Nova descrição da imagem";

// 4. Alteração de estilos inline (Apenas para valores dinâmicos)
const p2 = document.querySelector("#p2");
p2.style.color = "blue";
p2.style.marginTop = "20px";

// 5. Manipulação de Classes CSS (Prática recomendada para estilização)
const divAlerta = document.querySelector(".alerta");
divAlerta.classList.add("alerta-sucesso"); // Adiciona classe
divAlerta.classList.remove("alerta-erro"); // Remove classe
divAlerta.classList.toggle("oculto");      // Alterna a classe (adiciona se não tiver, remove se tiver)

Nota: Evite o uso da função document.write(). Trata-se de uma prática obsoleta que sobrescreve todo o documento HTML caso executada após o carregamento da página.

É possível navegar pela árvore do DOM através de relações estruturais (pais, filhos e irmãos). Recomenda-se utilizar as propriedades baseadas em Element em vez de Node, pois ignoram nós de texto em branco (quebras de linha no HTML).

const container = document.querySelector("#demo");

// Navegação Moderna (Focada em Elementos HTML)
const pai = container.parentElement;
const filhos = container.children; // Retorna uma HTMLCollection apenas com tags filhas
const primeiroFilho = container.firstElementChild;
const ultimoFilho = container.lastElementChild;
const proximoIrmao = container.nextElementSibling;
const irmaoAnterior = container.previousElementSibling;

// Acesso direto ao primeiro filho
const textoPrimeiroFilho = filhos[0].textContent;

Criação de Elementos Dinâmicos

A inserção de novos componentes na interface envolve a criação de elementos na memória e sua posterior anexação à árvore do DOM.

// 1. Criação de um novo elemento <div>
const novaDiv = document.createElement("div");

// 2. Configuração do elemento
novaDiv.textContent = "Conteúdo gerado via JS";
novaDiv.classList.add("box-destaque");

// 3. Seleção do nó pai onde o elemento será inserido
const elementoPai = document.querySelector("#secao-principal");

// 4. Inserção no DOM
elementoPai.append(novaDiv); // append() é o padrão moderno, substituindo appendChild()

Eventos e Interatividade

A interatividade no lado do cliente ocorre por meio do mapeamento de eventos (cliques, digitação, envio de formulários, redimensionamento de janela).

Má Prática (Evite): O uso de atributos de evento diretamente no HTML (ex: <button onclick="funcao()">) fere o princípio de separação de responsabilidades. O HTML deve conter apenas a estrutura, e o JS o comportamento.

Padrão Moderno (addEventListener):

A interface addEventListener permite vincular múltiplas funções a um mesmo evento sem sobrescrever ouvintes anteriores.

// Seleção do botão
const botaoEnviar = document.querySelector("#btnEnviar");

// Declaração da função de callback (Arrow Function)
const processarClique = (event) => {
    // O objeto 'event' (ou 'e') contém os metadados do evento disparado
    
    // event.target aponta para o elemento exato que acionou o evento
    event.target.textContent = "Processando...";
    event.target.classList.add("desativado");
    
    console.log("Botão clicado nas coordenadas: X:", event.clientX, "Y:", event.clientY);
};

// Vinculação do ouvinte de evento
botaoEnviar.addEventListener("click", processarClique);

Atribuindo eventos a múltiplos elementos

Se o sistema precisar capturar eventos de uma lista de elementos semelhantes, utilize um laço de repetição (forEach) sobre a NodeList gerada pelo querySelectorAll.

// Seleciona todos os parágrafos com a classe 'clicavel'
const paragrafos = document.querySelectorAll("p.clicavel");

paragrafos.forEach((paragrafo) => {
    paragrafo.addEventListener("click", (e) => {
        // Altera a cor de fundo do elemento específico que foi clicado
        e.target.style.backgroundColor = "yellow";
    });
});