Eventos no DOM
Esta aula aborda a manipulação de eventos no DOM com JavaScript, incluindo o uso de addEventListener, o objeto event, tipos comuns de eventos e a remoção de listeners. O conteúdo é prático e progressivo, ideal para alunos intermediários.
Eventos são ações ou ocorrências que acontecem no navegador, como cliques, teclas pressionadas ou carregamento de página. Manipular eventos é essencial para criar interfaces interativas e dinâmicas. Nesta aula, você aprenderá a registrar, gerenciar e remover ouvintes de eventos (listeners) no DOM, além de explorar o objeto event que carrega informações detalhadas sobre cada ocorrência.
Dominar eventos no DOM permite controlar a interação do usuário com a página, desde validação de formulários até animações complexas. Vamos aos conceitos fundamentais.
addEventListener
O método addEventListener é a forma moderna e recomendada de associar uma função a um evento em um elemento do DOM. Ele aceita três parâmetros: o tipo do evento (string), a função de callback (handler) e um objeto opcional de opções (como once, capture ou passive).
Diferente de atributos inline (como onclick), addEventListener permite adicionar múltiplos listeners para o mesmo evento no mesmo elemento, sem sobrescrever outros. Além disso, oferece mais controle sobre a propagação e a captura de eventos.
// Seleciona o elemento
const botao = document.getElementById('meuBotao');
// Define a função de callback
function handleClick() {
console.log('Botão clicado!');
}
// Adiciona o listener
botao.addEventListener('click', handleClick);
// Exemplo com função anônima
botao.addEventListener('click', function() {
alert('Outro handler');
});
// Usando arrow function
botao.addEventListener('click', () => console.log('Arrow function'));
O terceiro parâmetro pode ser um objeto com opções como once (executa apenas uma vez), capture (ativa a fase de captura) e passive (indica que o listener não chamará preventDefault(), melhorando performance em scroll, por exemplo).
// Executa apenas uma vez
botao.addEventListener('click', function() {
console.log('Executado apenas uma vez');
}, { once: true });
// Na fase de captura (padrão é false - bubbling)
document.addEventListener('click', function() {
console.log('Captura');
}, true);
Objeto event
Quando um evento é disparado, o navegador cria um objeto event que contém propriedades e métodos relacionados à ocorrência. Esse objeto é passado automaticamente como argumento para a função de callback. Você pode nomeá-lo como preferir (comum usar e, evt ou event).
Propriedades importantes incluem target (elemento que disparou o evento), currentTarget (elemento ao qual o listener está associado), type (tipo do evento), preventDefault() (cancela ação padrão), stopPropagation() (interrompe propagação) e stopImmediatePropagation() (interrompe propagação e outros listeners do mesmo elemento).
document.querySelector('a').addEventListener('click', function(event) {
event.preventDefault(); // evita navegar para o link
console.log('Link clicado, mas sem navegação');
console.log('Target:', event.target);
console.log('Type:', event.type);
});
// Exemplo de propagação
document.getElementById('pai').addEventListener('click', function(e) {
console.log('Clicou no pai');
});
document.getElementById('filho').addEventListener('click', function(e) {
e.stopPropagation(); // não propaga para o pai
console.log('Clicou no filho');
});
Para eventos de teclado, o objeto event possui key, code, ctrlKey, entre outros. Para mouse, clientX, clientY, button, etc.
Tipos comuns
Existem dezenas de tipos de eventos no DOM. Os mais utilizados incluem:
- mouse:
click,dblclick,mouseenter,mouseleave,mousemove,mousedown,mouseup - teclado:
keydown,keyup,keypress(depreciado) - formulário:
submit,change,input,focus,blur - documento/janela:
DOMContentLoaded,load,resize,scroll,unload - toque (mobile):
touchstart,touchend,touchmove
Exemplo prático com evento de teclado:
document.addEventListener('keydown', function(event) {
console.log('Tecla pressionada:', event.key);
if (event.key === 'Enter') {
alert('Enter pressionado!');
}
});
Exemplo com evento de formulário:
const form = document.getElementById('meuForm');
form.addEventListener('submit', function(e) {
e.preventDefault(); // evita recarregar a página
const dados = new FormData(form);
console.log('Dados do formulário:', Object.fromEntries(dados));
});
Removendo listeners
Para remover um listener, use o método removeEventListener com os mesmos parâmetros usados na adição (tipo, função e opções). É crucial que a função de callback seja a mesma referência; não é possível remover listeners anônimos a menos que você mantenha a referência em uma variável.
function handleClick() {
console.log('Removendo este listener');
}
botao.addEventListener('click', handleClick);
// Mais tarde, remove
botao.removeEventListener('click', handleClick);
// Tentativa de remover função anônima (não funciona)
botao.addEventListener('click', function() {
console.log('Nunca será removido');
});
// botao.removeEventListener('click', function() {...}); // não remove!
Para listeners com opções, passe o mesmo objeto de opções (a referência deve ser a mesma).
const options = { once: true };
botao.addEventListener('click', handleClick, options);
botao.removeEventListener('click', handleClick, options);
Uma boa prática é sempre remover listeners quando eles não forem mais necessários, especialmente em componentes que são destruídos, para evitar vazamento de memória.
Boas práticas e observações finais
Prefira addEventListener em vez de atributos HTML como onclick. Isso mantém a separação entre comportamento e estrutura. Use delegação de eventos sempre que possível: em vez de adicionar listeners a vários elementos filhos, adicione um único listener ao pai e verifique event.target. Isso melhora performance e simplifica o código.
Evite funções anônimas se precisar remover o listener depois. Lembre-se de que a propagação de eventos ocorre em três fases: captura (do document até o target), alvo (target) e bolha (do target de volta ao document). O terceiro parâmetro de addEventListener controla em qual fase o listener é executado (padrão é fase de bolha).
Referências
- MDN: addEventListener
- MDN: Event
- MDN: Referência de Eventos
- W3Schools: DOM Event Listener
- JavaScript.info: Browser Events
- MDN: stopPropagation
Exercícios
Crie um botão que, ao ser clicado, exiba um alerta com a mensagem "Olá, mundo!". Use
addEventListener.✓ Resposta:const btn = document.getElementById('meuBotao'); btn.addEventListener('click', function() { alert('Olá, mundo!'); });Adicione um evento de teclado que, ao pressionar a tecla 'Escape', exiba no console "Tecla Escape pressionada".
✓ Resposta:document.addEventListener('keydown', function(event) { if (event.key === 'Escape') { console.log('Tecla Escape pressionada'); } });Utilize o objeto
eventpara evitar que um link (<a>) navegue para outra página. Em vez disso, exiba o href no console.✓ Resposta:const link = document.querySelector('a'); link.addEventListener('click', function(event) { event.preventDefault(); console.log('Link clicado, href:', event.target.href); });Crie um listener que execute apenas uma vez (use a opção
once). Após o clique, o listener não deve mais responder.✓ Resposta:const btn = document.getElementById('meuBotao'); btn.addEventListener('click', function() { console.log('Este listener será executado apenas uma vez'); }, { once: true });Adicione um listener a um botão e, em seguida, remova-o usando
removeEventListener. Verifique se o listener foi removido (o botão não deve mais responder).✓ Resposta:function handleClick() { console.log('Botão clicado'); } const btn = document.getElementById('meuBotao'); btn.addEventListener('click', handleClick); // Remove após 3 segundos setTimeout(() => { btn.removeEventListener('click', handleClick); console.log('Listener removido'); }, 3000);