W3docs

Introdução aos Eventos de Browser em JavaScript

Aprenda como funcionam os eventos de browser em JavaScript: três formas de adicionar handlers, addEventListener vs onclick, o objeto de evento e muito mais.

Dominando os Eventos de Browser em JavaScript

Um evento de browser é um sinal de que algo aconteceu na página — o usuário clicou em um botão, uma tecla foi pressionada, uma imagem terminou de carregar, a janela foi redimensionada. Reagir a esses sinais é o que transforma um documento estático em uma aplicação interativa.

Este guia explica o que são eventos, as três formas de escutá-los (e qual delas preferir), o que o objeto de evento oferece, como parar de escutar, e apresenta seis exemplos práticos e executáveis do mundo real. Se você é novo na linguagem, comece com a introdução ao JavaScript primeiro.

Entendendo os Eventos de Browser

Um evento é uma ação ou ocorrência que o browser detecta e permite que seu código responda. Os eventos se dividem em dois grandes grupos:

  • Eventos orientados ao usuário — clicar com o mouse, digitar, mover o ponteiro, enviar um formulário.
  • Eventos orientados ao sistema — a página terminar de carregar, uma imagem falhar ao carregar, uma animação CSS terminar, a janela ser redimensionada.

Tipos de Eventos

Aqui estão alguns dos eventos mais comuns, agrupados por categoria:

CategoriaEventos
Mouseclick, dblclick, mouseover, mouseout, mousedown, mouseup
Tecladokeydown, keyup (keypress está obsoleto)
Formuláriosubmit, change, input, focus, blur
Documento / janelaDOMContentLoaded, load, resize, scroll, beforeunload

Cada categoria tem seu próprio capítulo dedicado: veja eventos de mouse, eventos de teclado, eventos de envio de formulário e eventos de carregamento de recursos.

Três Formas de Adicionar Event Handlers

Existem três formas de reagir a um evento. Elas estão listadas da menos para a mais flexível.

1. Atributo HTML (onclick="...") — rápido, mas mistura JavaScript na sua marcação e permite apenas um handler. Evite em projetos reais.

<button onclick="alert('Button clicked!')">Click Me!</button>

2. Propriedade DOM (element.onclick) — mantém o código em JavaScript, mas atribuir um novo handler sobrescreve o anterior, portanto ainda permite apenas um handler por evento.

<button id="myButton">Click Me!</button>
document.getElementById('myButton').onclick = function () {
  alert('Button clicked!');
};

3. addEventListener (recomendado) — a abordagem padrão. Você pode anexar vários handlers para o mesmo evento, controlar a fase de captura/borbulhamento e remover o handler posteriormente.

<button id="myButton">Click Me!</button>
document.getElementById('myButton').addEventListener('click', function () {
  alert('Button clicked!');
});

addEventListener é preferido porque permite registrar múltiplos listeners para o mesmo evento e oferece controle mais fino sobre o tratamento de eventos — por exemplo, chamando event.stopPropagation() ou event.preventDefault(). Ele também aceita um object de opções: { once: true } executa o handler uma única vez, e { capture: true } escuta durante a fase de captura (veja bubbling e capturing).

Removendo um Event Listener

Um listener permanece anexado até que você o remova (ou o elemento seja coletado pelo garbage collector). Para removê-lo, você deve passar a mesma referência de função que foi adicionada — uma função anônima inline não pode ser removida porque não há referência a ela.

function handleClick() {
  console.log('clicked');
}

const btn = document.getElementById('myButton');
btn.addEventListener('click', handleClick);

// later — stops the handler from firing again
btn.removeEventListener('click', handleClick);

O Objeto de Evento

Quando um evento é disparado, o browser cria um objeto de evento descrevendo o que aconteceu e o passa como primeiro argumento para o seu handler. Propriedades úteis incluem:

  • event.type — o nome do evento, por exemplo "click".
  • event.target — o elemento que efetivamente disparou o evento.
  • event.currentTarget — o elemento ao qual o listener está anexado (igual a this em um handler de função regular).
  • event.preventDefault() — cancela a ação padrão do browser (por exemplo, seguir um link).
  • event.stopPropagation() — impede que o evento borbulhe para elementos ancestrais.
<button id="myButton">Click Me!</button>
<div style="margin-top:10px;" id="eventInfo"></div>

<script>
  document.getElementById('myButton').addEventListener('click', function(event) {
    var eventInfo = 'Event Type: ' + event.type + '<br />Clicked Element: ' + event.target.tagName;
    document.getElementById('eventInfo').innerHTML = eventInfo;
  });
</script>

Exemplos Práticos de Tratamento de Eventos de Browser

Vamos explorar alguns exemplos práticos que mostram como tratar eventos de browser em cenários do mundo real.

Exemplo 1: Evento de Envio de Formulário

Tratando o envio de um formulário para validar a entrada antes de enviar dados ao servidor:

<form id="loginForm">
  Username: <input type="text" name="username" required />
  Password: <input type="password" name="password" required />
  <button type="submit">Login</button>
</form>

<script>
  document.getElementById('loginForm').addEventListener('submit', function(event) {
    event.preventDefault(); // Prevent the form from submitting normally
    if (this.username.value.length < 4 || this.password.value.length < 4) {
      alert('Username and password must be at least 4 characters long.');
    } else {
      this.submit(); // Submit the form manually if validation passes
      alert('successfully submitted');
    }
  });
</script>

(Nota: Uma função regular é usada aqui em vez de uma arrow function para preservar o contexto de this, permitindo que this.username e this.password referenciem corretamente os elementos do formulário.)

Exemplo 2: Tratando Eventos Mouse Over e Mouse Out

Alterando o estilo de um botão quando o mouse está sobre ele e redefinindo quando o mouse sai:

<button id="hoverButton">Hover Over Me!</button>

<script>
  const button = document.getElementById('hoverButton');
  button.addEventListener('mouseover', function() {
    this.style.backgroundColor = 'green';
  });
  button.addEventListener('mouseleave', function() {
    this.style.backgroundColor = '';
  });
</script>

Exemplo 3: Eventos de Teclado

Executando uma função quando a tecla Enter é pressionada:

<input type="text" id="inputField" placeholder="Type something and press Enter" />

<script>
  document.getElementById('inputField').addEventListener('keydown', function(event) {
    if (event.key === 'Enter') {
      alert('You pressed Enter!');
    }
  });
</script>

Exemplo 4: Funcionalidade de Arrastar e Soltar

Implementando arrastar e soltar para uma transferência simples de imagem dentro de uma página web:

<span>Drop image below</span>
<div id="dragArea" style="width: 300px; height: 300px; border: 2px dashed #ccc;">
  
</div>
<img id="draggableImage" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150'%3E%3Crect width='150' height='150' fill='%234f46e5'/%3E%3Ctext x='75' y='80' fill='white' font-size='18' text-anchor='middle'%3EDrag me%3C/text%3E%3C/svg%3E" draggable="true" style="width: 150px; height: 150px;">

<script>
  const dragArea = document.getElementById('dragArea');
  const draggableImage = document.getElementById('draggableImage');

  // Event listener for the drag start
  draggableImage.addEventListener('dragstart', function(event) {
    event.dataTransfer.setData("text/plain", event.target.id);
  });

  // Event listener for dragging over the drag area
  dragArea.addEventListener('dragover', function(event) {
    event.preventDefault(); // Necessary to allow the drop
  });

  // Event listener for drop
  dragArea.addEventListener('drop', function(event) {
    event.preventDefault(); // Prevent default behavior (like opening as link for some elements)
    const data = event.dataTransfer.getData("text/plain");
    const image = document.getElementById(data);
    dragArea.appendChild(image);
  });
</script>

Explicação:

  • Início do Arraste: Quando você começa a arrastar a imagem, o ID da imagem é salvo nos dados de arrastar.
  • Arraste Sobre: Impedir a ação padrão é necessário para permitir o soltar.
  • Soltar: Ao soltar, a imagem é movida para a área de destino.

Exemplo 5: Eventos de Início e Fim de Animação

Usando animações CSS e tratando seu início e fim com JavaScript:

<div id="animateBox" style="width: 100px; height: 100px; background: red; position: relative; animation: moveBox 5s 2;"></div>
<div id="animationStatus"></div>

<style>
  @keyframes moveBox {
    0% { left: 0; }
    50% { left: 200px; }
    100% { left: 0; }
  }
</style>

<script>
  const box = document.getElementById('animateBox');
  const statusDisplay = document.getElementById('animationStatus');

  box.addEventListener('animationstart', function() {
    statusDisplay.innerHTML = 'Animation started';
  });

  box.addEventListener('animationend', function() {
    statusDisplay.innerHTML = 'Animation ended';
  });

  box.addEventListener('animationiteration', function() {
    statusDisplay.innerHTML = 'Animation iteration';
  });
</script>

(Nota: animationstart e eventos relacionados são padrão nos browsers modernos. Versões mais antigas do Safari podem exigir prefixos de fabricante como -webkit-animationstart, mas os nomes padrão são recomendados para o desenvolvimento atual.)

Explicação:

  • animationstart é disparado uma vez quando a animação começa.
  • animationiteration é disparado no início de cada repetição — útil quando uma animação está configurada para ser executada várias vezes.
  • animationend é disparado uma vez quando a animação termina. A div #animationStatus é atualizada em cada evento para fornecer feedback em tempo real na página.

Exemplo 6: Eventos Personalizados

Criando e despachando eventos personalizados para tratar cenários específicos da aplicação:

<button id="customEventButton">Trigger Custom Event</button>

<script>
  // Creating a custom event
  const myEvent = new CustomEvent('myCustomEvent', {
    detail: { message: 'Custom event triggered' }
  });

  // Event listener for custom event
  document.addEventListener('myCustomEvent', function(event) {
    alert('Event Message: ' + event.detail.message);
  });

  // Dispatch the custom event when button is clicked
  document.getElementById('customEventButton').addEventListener('click', function() {
    document.dispatchEvent(myEvent);
  });
</script>

Explicação:

  • Criação do Evento Personalizado: Define um evento personalizado com dados adicionais (detail contendo uma mensagem).
  • Tratamento do Evento: Configura um listener para o evento personalizado que exibe um alerta com a mensagem do detalhe do evento.
  • Disparo do Evento: Dispara o evento personalizado ao clicar no botão.

Boas Práticas

  • Prefira addEventListener em vez de atributos onclick inline — mantém o comportamento fora da sua marcação e suporta múltiplos handlers.
  • Use funções regulares quando precisar que this se refira ao elemento; use arrow functions quando não precisar, e leia event.currentTarget em vez disso.
  • Remova listeners que você não precisa mais com removeEventListener (passando a mesma referência de função) para evitar vazamentos de memória, especialmente em aplicações de página única.
  • Anexe um listener a um elemento pai em vez de muitos a cada filho ao lidar com listas — essa técnica, chamada de delegação de eventos, baseia-se no event bubbling.
  • Limite a frequência de eventos de alta frequência como scroll e resize para evitar executar trabalho custoso a cada disparo; veja otimização de desempenho do DOM.

Conclusão

Os eventos de browser são a ponte entre o que o usuário faz e como seu código responde. Os pontos principais: use addEventListener para flexibilidade, leia o que você precisa do objeto de evento, chame preventDefault() ou stopPropagation() quando precisar substituir o comportamento padrão, e remova listeners que você não precisa mais.

A partir daqui, explore os capítulos dedicados sobre eventos de mouse, eventos de teclado, tratamento de envio de formulários e despacho de eventos personalizados para criar interfaces mais ricas e orientadas a eventos.

Prática

Prática
Quais são os diferentes aspectos dos eventos de browser em JavaScript?
Quais são os diferentes aspectos dos eventos de browser em JavaScript?
Prática
Quais afirmações sobre addEventListener estão corretas?
Quais afirmações sobre addEventListener estão corretas?
Was this page helpful?