Eventos em JavaScript
Eventos são "sinais" enviados pelo usuário ou pelo navegador — quando um usuário clica em um botão, pressiona uma tecla, envia um formulário, ou o navegador termina de carregar uma página... tudo isso são eventos. Seu código "ouve" esses eventos e responde no momento certo. É como uma campainha tocando e você abrindo a porta — a campainha é o evento, abrir a porta é a resposta.
Métodos de Vinculação de Eventos
O JavaScript tem três formas de vincular manipuladores de eventos a elementos:
1. Atributos HTML (Não Recomendado)
<button onclick="alert('Não use este método')">Clique aqui</button>
HTML e JS são misturados, dificultando a manutenção. Não recomendado.
2. Propriedades do DOM
<button id="myBtn">Clique aqui</button>
<script>
const btn = document.getElementById('myBtn');
btn.onclick = function() {
console.log('Clicado');
};
</script>
HTML e JS são separados, mas cada evento só pode ter um manipulador — atribuições posteriores sobrescrevem as anteriores.
3. addEventListener (Recomendado)
<button id="btn1">Botão 1</button>
<button id="btn2">Botão 2</button>
<script>
const btn1 = document.getElementById('btn1');
const btn2 = document.getElementById('btn2');
btn1.addEventListener('click', function() {
console.log('Manipulador 1');
});
btn1.addEventListener('click', function() {
console.log('Manipulador 2');
});
</script>
O mesmo evento pode ter múltiplos manipuladores, e você pode usar removeEventListener para removê-los. Esta é a abordagem mais flexível.
addEventListener. Ele não sobrescreve listeners existentes e permite controlar a fase de propagação/captura. É a única escolha para desenvolvimento moderno.
addEventListener e removeEventListener
<script>
element.addEventListener('nomeEvento', manipulador, opcoes);
element.removeEventListener('nomeEvento', manipulador);
</script>
removeEventListener requer a mesma referência de função que addEventListener. Funções anônimas não podem ser removidas! Se precisar remover um manipulador, defina a função separadamente.
<button id="btn">Teste</button>
<script>
const btn = document.getElementById('btn');
function manipulador() { console.log('Dispara apenas uma vez'); }
btn.addEventListener('click', manipulador);
btn.removeEventListener('click', manipulador); // Removido com sucesso
btn.addEventListener('click', function() { console.log('Anônima'); });
btn.removeEventListener('click', function() { console.log('Anônima'); }); // Remoção falha!
</script>
Tipos Comuns de Eventos
| Categoria | Evento | Descrição |
|---|---|---|
| Mouse | click, dblclick |
Clique único, clique duplo |
| Mouse | mouseover, mouseout |
Mouse entra/sai |
| Teclado | keydown, keyup |
Tecla pressionada/solta |
| Formulário | submit |
Formulário enviado |
| Formulário | change |
Valor mudou após perder foco |
| Formulário | input |
Valor muda em tempo real (cada caractere digitado) |
| Página | load |
Página e todos os recursos totalmente carregados |
| Página | DOMContentLoaded |
Parsing do HTML completo (não espera imagens) |
change vs input: input dispara conforme você digita, change dispara após terminar de digitar e perder foco. Use input para busca em tempo real, change para validação de formulário.
Objeto de Evento
Manipuladores de eventos recebem um parâmetro de objeto de evento, geralmente chamado event ou abreviado como e.
| Propriedade/Método | Descrição |
|---|---|
e.target |
O elemento que disparou o evento (o que foi realmente clicado) |
e.type |
Tipo do evento, como 'click' |
e.preventDefault() |
Prevenir comportamento padrão (ex: impedir navegação de link, envio de formulário) |
e.stopPropagation() |
Parar propagação do evento |
Exemplo: Contador de Cliques em Botão
<button id="counter">Clicado 0 vezes</button>
<script>
const btn = document.getElementById('counter');
let count = 0;
btn.addEventListener('click', function(e) {
count++;
btn.textContent = 'Clicado ' + count + ' vezes';
console.log('Tipo do evento:', e.type);
console.log('Elemento alvo:', e.target.tagName);
});
</script>
Exemplo: Detecção de Teclado
<p>Pressione qualquer tecla para ver as informações</p>
<div id="info" style="padding: 10px; border: 1px solid #ccc; min-height: 30px;"></div>
<script>
const info = document.getElementById('info');
document.addEventListener('keydown', function(e) {
info.innerHTML = 'Tecla: <b>' + e.key + '</b> | KeyCode: ' + e.keyCode + ' | Ctrl: ' + e.ctrlKey + ' | Shift: ' + e.shiftKey;
});
</script>
Exemplo: Interceptação de Formulário
<form id="myForm">
<input type="text" id="name" placeholder="Digite o nome" required>
<button type="submit">Enviar</button>
</form>
<p id="result"></p>
<script>
const form = document.getElementById('myForm');
const result = document.getElementById('result');
form.addEventListener('submit', function(e) {
e.preventDefault();
const name = document.getElementById('name').value;
result.textContent = 'Olá, ' + name + '! O formulário foi interceptado, não enviado de fato.';
});
</script>
Exemplo: Delegação de Eventos
<ul id="menu">
<li>Início</li>
<li>Sobre</li>
<li>Contato</li>
<li>Ajuda</li>
</ul>
<p id="selected"></p>
<script>
const menu = document.getElementById('menu');
const selected = document.getElementById('selected');
menu.addEventListener('click', function(e) {
if (e.target.tagName === 'LI') {
selected.textContent = 'Você selecionou: ' + e.target.textContent;
}
});
</script>
e.target para determinar qual filho foi realmente clicado. Você não precisa vincular eventos a cada li individualmente, e novos elementos filhos funcionam automaticamente. Este é o poder do mecanismo de propagação.
Propagação e Captura de Eventos
A propagação de eventos do DOM tem três fases:
- Fase de captura: O evento viaja de
windowaté o elemento alvo - Fase alvo: O evento alcança o elemento que realmente disparou
- Fase de propagação: O evento sobe do elemento alvo de volta para
window
Por padrão, addEventListener dispara durante a fase de propagação. Defina o terceiro parâmetro como true para disparar durante a fase de captura.
window
↓ captura
document
↓
body
↓
elemento alvo ← fase alvo
↑ propagação
body
↑
document
↑
window
e.stopPropagation() pode parar a propagação do evento, mas não use em excesso — pode quebrar a delegação de eventos.
📖 Resumo
- Entre os três métodos de vinculação,
addEventListeneré o único recomendado — suporta múltiplos listeners, é removível, e controla a fase de propagação. removeEventListenerrequer a mesma referência de função; funções anônimas não podem ser removidas.- Propriedades principais do objeto de evento
e:target(quem disparou),type(qual evento),preventDefault()(prevenir comportamento padrão),stopPropagation()(parar propagação). changevsinput: o primeiro dispara no blur, o segundo dispara em tempo real.- A propagação de eventos torna a "delegação de eventos" possível — ouvir no pai, tratar filhos com
e.target. DOMContentLoadeddispara antes deload, adequado para inicialização do DOM.
❓ Perguntas Frequentes
P: Qual a diferença entre
e.targetee.currentTarget? R:e.targeté o elemento que realmente disparou o evento (o que você clicou),e.currentTargeté o elemento que está executando o manipulador (o que tem o listener). Na delegação de eventos eles são diferentes; na vinculação direta são iguais.
P: Por que a página atualiza após o envio do formulário? R: O comportamento padrão do evento
submitdo<form>é enviar e atualizar a página. Chamee.preventDefault()para impedir, depois trate os dados com JS.
P:
onclickeaddEventListener('click')podem ser usados juntos? R: Sim, mas a atribuição deonclicksobrescreve funções previamente vinculadas viaonclick, enquantoaddEventListenernão. Misturar pode ser confuso — fique comaddEventListenerpara tranquilidade.
📝 Atividades
- Básico: Crie um botão e use
addEventListenerpara vincular um eventoclick. Cada clique aumenta a largura do botão em 10px. - Intermediário: Implemente um instrumento musical — ouça eventos
keydown. Quando A/S/D/F/G forem pressionados, exiba nomes de notas diferentes (Do/Re/Mi/Fa/Sol) na página. - Desafio: Use delegação de eventos para implementar um menu dinâmico — uma lista
ulcom um botão "Adicionar Item". Itensliadicionados recentemente também devem ser destacados quando clicados (sem precisar vincular eventos a novosliindividualmente). - Bônus: Implemente uma busca em tempo real com evento
input— conforme você digita no campo de input, a lista abaixo só mostra itens contendo o texto digitado.



