Programação Web 2

Eventos e Interatividade

Prof. Me. Danilo Bueno

O que é um evento?

Um evento é uma ação que acontece no navegador:

  • Usuário clicou num botão
  • Usuário pressionou uma tecla
  • Formulário foi enviado
  • Página terminou de carregar

O JavaScript não verifica continuamente se algo mudou.
Em vez disso, você registra uma função que será chamada automaticamente quando o evento ocorrer.

addEventListener

elemento.addEventListener("tipo-do-evento", function(event) {  // executado quando o evento dispara});

Exemplo:

const btn = document.querySelector("#btn-salvar");btn.addEventListener("click", function(event) {  console.log("botão clicado!");});
  • Primeiro argumento: tipo do evento (string)
  • Segundo argumento: função callback
  • O callback recebe o objeto event automaticamente

Tipos de eventos — mouse

Evento Quando dispara
click Clique do mouse
dblclick Duplo clique
mouseenter Cursor entra na área do elemento
mouseleave Cursor sai da área do elemento
const card = document.querySelector(".card");card.addEventListener("mouseenter", function() {  card.classList.add("destaque");});card.addEventListener("mouseleave", function() {  card.classList.remove("destaque");});

Tipos de eventos — teclado

Evento Quando dispara
keydown Tecla pressionada
keyup Tecla solta
document.addEventListener("keydown", function(event) {  console.log(event.key); // "Escape", "Enter", "a", "ArrowUp"...  if (event.key === "Escape") {    fecharMenu();  }});

Por que o listener vai no document?
Teclas não pertencem a nenhum elemento específico — são globais.
O document captura independente de qual elemento está em foco.

Tipos de eventos — formulário e janela

Formulário:

const campo = document.querySelector("#busca");campo.addEventListener("input", function(event) {  console.log(event.target.value); // valor atual a cada caractere});form.addEventListener("submit", function(event) {  event.preventDefault(); // impede recarregamento da página});

Janela:

document.addEventListener("DOMContentLoaded", function() {  // HTML pronto — seguro para selecionar elementos});

O objeto Event

Todo callback recebe um objeto event com informações sobre o que aconteceu.

btn.addEventListener("click", function(event) {  console.log(event.type);          // "click"  console.log(event.target);        // o elemento clicado  console.log(event.currentTarget); // o elemento com o listener});

event.target vs event.currentTarget

<ul id="lista">  <li><button class="btn-excluir">Excluir</button></li>  <li><button class="btn-excluir">Excluir</button></li></ul>
const lista = document.querySelector("#lista");lista.addEventListener("click", function(event) {  console.log(event.target);        // <button class="btn-excluir"> ← o que foi clicado  console.log(event.currentTarget); // <ul id="lista"> ← quem tem o listener});

event.target — o elemento exato que recebeu o clique (pode ser um filho)
event.currentTarget — o elemento que tem o addEventListener

classList.toggle

toggle adiciona a classe se não existir — remove se já existir.

const menu = document.querySelector("#menu");const btn = document.querySelector("#btn-menu");btn.addEventListener("click", function() {  menu.classList.toggle("aberto");  // 1ª chamada: adiciona "aberto"  // 2ª chamada: remove "aberto"  // 3ª chamada: adiciona "aberto" ...});
Método Comportamento
add("x") Adiciona sempre
remove("x") Remove sempre
toggle("x") Adiciona se ausente, remove se presente
contains("x") Retorna true/false

Verificando o estado antes de agir

Use contains para condicionar ações ao estado atual.

const modal = document.querySelector("#modal");document.addEventListener("keydown", function(event) {  if (event.key === "Escape") {    // só age se o modal estiver visível    if (!modal.classList.contains("escondido")) {      fecharModal();    }  }});

Atributos data-* e dataset

Atributos data-* guardam dados em elementos HTML, acessíveis via JavaScript.

<button class="btn-detalhes" data-id="3" data-categoria="livros">  Ver detalhes</button>
const btn = document.querySelector(".btn-detalhes");console.log(btn.dataset.id);        // "3" (sempre string)console.log(btn.dataset.categoria); // "livros"const id = Number(btn.dataset.id);  // converte para número

Nomes com hífen no HTML → camelCase no JS:
data-nome-completo → dataset.nomeCompleto

Event Bubbling

Quando um evento ocorre num elemento, ele se propaga para cima na árvore DOM.

Clique em <button> dentro de <div> dentro de <section>:

  button  →  div  →  section  →  body  →  html  →  document

Todos os listeners de "click" nesses elementos são chamados.

document.querySelector("section").addEventListener("click", function(event) {  // dispara quando qualquer elemento DENTRO da section for clicado  console.log("clicou em:", event.target.tagName);});

Event Delegation

Usar bubbling estrategicamente: colocar o listener no pai em vez de em cada filho.

// ❌ Sem delegation — um listener por botãodocument.querySelectorAll(".btn-excluir").forEach(function(btn) {  btn.addEventListener("click", excluirItem);});// ✅ Com delegation — um listener no containerconst lista = document.querySelector("#lista-itens");lista.addEventListener("click", function(event) {  if (event.target.classList.contains("btn-excluir")) {    excluirItem(event.target);  }});

Por que usar delegation?

Situação Sem delegation Com delegation
10 botões 10 listeners 1 listener
Botões criados depois ❌ Não captura ✅ Captura
Código N forEach + addEventListener 1 addEventListener

Delegation funciona com elementos criados dinamicamente porque o listener está no container — que já existia antes.

stopPropagation

Para parar o bubbling manualmente:

const conteudo = document.querySelector(".modal-conteudo");const overlay = document.querySelector(".modal-overlay");// Clicar no overlay fecha o modaloverlay.addEventListener("click", function() {  fecharModal();});// Clicar no conteúdo NÃO deve fecharconteudo.addEventListener("click", function(event) {  event.stopPropagation(); // impede que o clique suba para o overlay});

Funções reutilizáveis

Extrair lógica repetida em funções nomeadas torna o código mais legível.

const modal = document.querySelector("#modal");function abrirModal(produto) {  document.querySelector("#modal-nome").textContent = produto.nome;  document.querySelector("#modal-preco").textContent = produto.preco;  document.body.style.overflow = "hidden";  modal.classList.remove("escondido");}function fecharModal() {  document.body.style.overflow = "";  modal.classList.add("escondido");}// Agora qualquer listener pode chamar abrirModal() ou fecharModal()

Resumo

Conceito O que é
addEventListener(tipo, fn) Registra função para executar quando evento ocorrer
event.target Elemento que disparou o evento
event.key Tecla pressionada ("Escape", "Enter", ...)
event.preventDefault() Cancela comportamento padrão do navegador
event.stopPropagation() Para o bubbling
classList.toggle(c) Alterna presença da classe
classList.contains(c) Verifica se classe está presente
dataset.nome Lê data-nome do elemento HTML
Event delegation Listener no pai, verificar event.target no callback

Obrigado!