Tratamento de Eventos no DOM
Aprenda o tratamento de eventos JavaScript no DOM: addEventListener, removeEventListener, o objeto event, preventDefault, bubbling e delegação de eventos, com exemplos executáveis.
Introdução aos Eventos JavaScript
Os eventos JavaScript são ações ou ocorrências que acontecem no navegador — um clique, o pressionamento de uma tecla, uma página terminando de carregar — que o seu código pode detectar e responder. Reagir a eventos é o que transforma uma página estática em uma aplicação interativa.
Este capítulo aborda as três formas de registrar manipuladores de eventos, os tipos de eventos mais comuns, o objeto event que todo manipulador recebe, como os eventos percorrem o DOM (bubbling e captura), e os padrões que mantêm páginas com muitos eventos rápidas e sem vazamentos de memória.
Três Formas de Tratar Eventos
Antes de analisar eventos específicos, é útil saber que existem três formas distintas de anexar um manipulador. Elas estão listadas da mais antiga para a mais flexível.
| Abordagem | Exemplo | Múltiplos manipuladores? | Recomendado |
|---|---|---|---|
| Atributo HTML inline | <button onclick="doX()"> | Não | Não — mistura marcação e lógica |
| Propriedade DOM | element.onclick = fn | Não (o último vence) | Apenas para casos simples |
addEventListener() | element.addEventListener("click", fn) | Sim | Sim — o padrão moderno |
<button id="propBtn">Click me</button>
<script>
const btn = document.getElementById("propBtn");
// 1. DOM property — assigning again overwrites the previous handler
btn.onclick = function () {
alert("Handled by the onclick property");
};
// 2. addEventListener — adds without overwriting; you can attach many
btn.addEventListener("click", function () {
console.log("Also handled by addEventListener");
});
</script>Ambos os manipuladores acima são executados ao clicar. Se você atribuir btn.onclick uma segunda vez, a primeira atribuição é silenciosamente perdida — o que é a principal razão pela qual addEventListener() é preferido. O restante deste capítulo usa addEventListener().
Eventos Comuns em JavaScript
Evento Click
O evento click é disparado quando o usuário pressiona e solta o botão principal do mouse (ou toca, em dispositivos touch) sobre um elemento. É o evento mais utilizado.
<button id="clickButton">Click Me</button>
<script>
document.getElementById("clickButton").addEventListener("click", function () {
alert("Button was clicked!");
});
</script>Neste exemplo, um ouvinte de evento é adicionado a um botão com o ID clickButton. Quando o botão é clicado, uma caixa de alerta com a mensagem "Button was clicked!" aparecerá.
Evento Mouseover
O evento mouseover é disparado quando o ponteiro do mouse move sobre um elemento. (Seu contraponto, mouseout, é disparado quando o ponteiro sai.)
<p id="mouseoverText">Hover over me!</p>
<script>
document.getElementById("mouseoverText").addEventListener("mouseover", function () {
this.style.color = "red";
});
</script>Neste exemplo, um ouvinte de evento é adicionado a um parágrafo com o ID mouseoverText. Quando o mouse é passado sobre o parágrafo, a cor do texto muda para vermelho.
Evento Keydown
O evento keydown é disparado quando o usuário pressiona uma tecla enquanto um elemento está em foco. O manipulador recebe um objeto event cuja propriedade event.key contém o valor da tecla.
<input type="text" id="inputField" placeholder="Type something..." />
<script>
document.getElementById("inputField").addEventListener("keydown", function (event) {
alert(`Key pressed: ${event.key}`);
this.value = '';
});
</script>Neste exemplo, um ouvinte de evento é adicionado a um campo de entrada com o ID inputField. Quando uma tecla é pressionada enquanto o campo de entrada está em foco, a tecla pressionada é exibida em uma caixa de alerta.
O Objeto Event
Todo manipulador é chamado com um argumento: o objeto event. Ele descreve o que aconteceu e expõe métodos para controlar o evento. Os membros mais úteis são:
event.target— o elemento no qual o evento realmente se originou (por exemplo, o botão exato clicado).event.currentTarget— o elemento ao qual o ouvinte está anexado. Dentro de uma função regular, é o mesmo quethis.event.type— o nome do evento, como"click".event.preventDefault()— cancela a ação padrão do navegador (seguir um link, enviar um formulário).event.stopPropagation()— impede que o evento continue a subir pelo DOM.
<a id="link" href="https://www.w3docs.com">Visit W3docs</a>
<script>
document.getElementById("link").addEventListener("click", function (event) {
event.preventDefault(); // stop the browser from navigating away
console.log("type:", event.type); // "click"
console.log("target id:", event.target.id); // "link"
});
</script>Aqui, preventDefault() impede que a página navegue, para que você possa executar sua própria lógica — um padrão comum para aplicações de página única e validação de formulário personalizada.
Dentro de uma arrow function, this não é vinculado novamente ao elemento. Use event.currentTarget (ou uma function regular) quando precisar de uma referência ao elemento ao qual o ouvinte está anexado. Veja arrow functions revisitadas para entender o motivo.
Adicionando Ouvintes de Eventos
O Método addEventListener()
O método addEventListener() anexa um manipulador de evento a um elemento sem sobrescrever os manipuladores existentes. Isso significa que você pode anexar múltiplos ouvintes — mesmo para o mesmo tipo de evento — a um único elemento. Sua assinatura é element.addEventListener(type, handler, options), onde options pode ajustar o comportamento (once, capture, passive).
<button id="multiEventButton">Click or Hover</button>
<script>
const button = document.getElementById("multiEventButton");
button.addEventListener("click", function () {
alert("Button clicked!");
});
button.addEventListener("mouseover", function () {
button.style.backgroundColor = "lightblue";
});
</script>Neste exemplo, dois ouvintes de evento são adicionados ao botão com o ID multiEventButton. Um ouvinte dispara um alerta quando o botão é clicado, e o outro muda a cor de fundo do botão quando o mouse passa sobre ele.
Use addEventListener() para anexar múltiplos ouvintes de evento ao mesmo elemento sem sobrescrever os manipuladores existentes.
Removendo Ouvintes de Eventos
O Método removeEventListener()
O método removeEventListener() desanexa um manipulador que foi anexado com addEventListener(). O detalhe importante: você deve passar a mesma referência de função exata que adicionou, por isso funções nomeadas são necessárias para remover um ouvinte posteriormente.
<button id="removeEventButton">Click Me</button>
<script>
function showAlert() {
alert("This will be removed after first click");
}
const button = document.getElementById("removeEventButton");
button.addEventListener("click", showAlert);
button.addEventListener("click", function () {
button.removeEventListener("click", showAlert);
});
</script>Neste exemplo, um ouvinte de evento que dispara um alerta é adicionado ao botão com o ID removeEventButton. Outro ouvinte de evento é adicionado para remover o ouvinte de alerta após o primeiro clique. Observe que removeEventListener requer uma referência ao exato mesmo objeto de função usado em addEventListener. Por isso funções anônimas não podem ser removidas posteriormente — cada declaração cria um novo e distinto objeto de função.
Aproveite a delegação de eventos para melhor desempenho, especialmente ao trabalhar com um grande número de elementos filhos.
Propagação de Eventos e Delegação
Quando um evento é disparado em um elemento, ele não para por aí. Por padrão, ele percorre duas fases: primeiro a captura (do topo do DOM até o alvo), depois o bubbling (do alvo de volta até a raiz). A maioria dos manipuladores é executada durante a fase de bubbling, por isso um clique em um botão também alcança um ouvinte de clique em seu elemento pai <div>.
Esse bubbling possibilita a delegação de eventos: em vez de anexar um ouvinte a cada filho, anexe um único ouvinte a um pai comum e leia event.target para descobrir qual filho foi realmente clicado.
<ul id="menu">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
<script>
// One listener handles clicks on any current OR future <li>
document.getElementById("menu").addEventListener("click", function (event) {
if (event.target.tagName === "LI") {
console.log("You clicked:", event.target.textContent);
}
});
</script>Um único ouvinte no <ul> cuida de cada <li>, incluindo os adicionados à lista posteriormente — muito mais eficiente do que configurar cada item individualmente. Para uma análise mais aprofundada das fases e do stopPropagation(), veja bubbling e captura.
Boas Práticas
Use a Delegação de Eventos
Adicione um único ouvinte de evento a um elemento pai para gerenciar os eventos de todos os elementos filhos. Isso melhora o desempenho e reduz o número de ouvintes de eventos.
Evite Funções Anônimas para Manipuladores de Eventos
Usar funções nomeadas para manipuladores de eventos facilita a remoção posterior e melhora a legibilidade do código.
Limpe os Ouvintes de Eventos
Certifique-se de que os ouvintes de eventos sejam removidos quando não forem mais necessários, para evitar vazamentos de memória e melhorar o desempenho.
Minimize o Número de Ouvintes de Eventos
Anexe ouvintes de eventos a elementos de nível superior em vez de a numerosos elementos individuais para reduzir o uso de memória e melhorar o desempenho.
Use a Opção once em addEventListener
Utilize a opção once para remover automaticamente o ouvinte de evento após ser disparado uma vez, prevenindo possíveis vazamentos de memória.
button.addEventListener("click", function handler() {
console.log("Triggered once");
}, { once: true });Previna Ações Padrão e Pare a Propagação de Forma Adequada
Use event.preventDefault() e event.stopPropagation() criteriosamente para controlar o comportamento dos eventos sem interferir em outros manipuladores.
Use Debounce ou Throttle em Manipuladores de Eventos
Use técnicas de debouncing ou throttling para otimizar o desempenho de manipuladores de eventos disparados com frequência, como eventos de scroll ou redimensionamento.
Conclusão
Dominar os eventos JavaScript é essencial para criar aplicações web dinâmicas e interativas. Ao entender como usar eventos como click, mouseover e keydown, e como adicionar e remover ouvintes de eventos com addEventListener() e removeEventListener(), você pode aprimorar significativamente as interações do usuário em suas páginas web.