Fundamentos de Eventos de Mouse em JavaScript
Aprenda eventos de mouse em JavaScript: click, dblclick, mousedown, mouseup, mousemove, mouseover vs mouseenter e contextmenu. Inclui o objeto MouseEvent (clientX, pageX, offsetX, button) com exemplos de arrastar e soltar e canvas.
Introdução
Em JavaScript, os eventos de mouse permitem que a sua página responda ao que um usuário faz com o ponteiro: clicar em um botão, passar o mouse sobre um link, arrastar um item ou clicar com o botão direito para abrir um menu. Conectar scripts a esses eventos é o que transforma um documento estático em uma interface interativa.
Este guia abrange o conjunto completo de eventos básicos de mouse, os dados disponíveis no objeto de evento (qual botão, onde está o ponteiro), a diferença importante entre mouseover e mouseenter, e vários exemplos executáveis — alternância de cores, menu de contexto personalizado, canvas de desenho e arrastar e soltar. Os eventos de mouse fazem parte da família mais ampla de eventos do navegador; se você é novo na adição de handlers, leia primeiro Manipulação de eventos no DOM.
Entendendo os Eventos de Mouse em JavaScript
Um evento de mouse é um sinal que o navegador dispara quando o usuário interage com a página usando um dispositivo apontador. Você responde a ele registrando um listener com addEventListener('eventName', handler). O handler recebe um objeto MouseEvent descrevendo o que aconteceu.
Principais Eventos de Mouse
| Evento | Disparado quando… |
|---|---|
click | Um botão é pressionado e solto no mesmo elemento. |
dblclick | O elemento é clicado duas vezes em rápida sucessão. |
mousedown | Um botão do mouse é pressionado. |
mouseup | Um botão do mouse é solto. |
mousemove | O ponteiro se move sobre o elemento (dispara muitas vezes). |
mouseover | O ponteiro entra no elemento ou em um de seus filhos (propaga). |
mouseout | O ponteiro sai do elemento ou de um de seus filhos (propaga). |
mouseenter | O ponteiro entra no elemento (não propaga). |
mouseleave | O ponteiro sai do elemento (não propaga). |
contextmenu | O botão direito é clicado, antes de o menu nativo abrir. |
Um click completo é na verdade três eventos em sequência: mousedown → mouseup → click. Conhecer a sequência ajuda quando um evento parece "engolir" outro.
Lendo o objeto MouseEvent
Cada handler de mouse recebe um objeto de evento com propriedades úteis:
event.clientX/event.clientY— posição do ponteiro relativa ao viewport (a janela visível).event.pageX/event.pageY— posição relativa ao documento inteiro, incluindo a rolagem.event.offsetX/event.offsetY— posição relativa à própria caixa do elemento alvo.event.button— qual botão:0= esquerdo,1= do meio,2= direito.event.ctrlKey/event.shiftKey/event.altKey/event.metaKey—truese aquela tecla modificadora estava pressionada durante o evento.event.target— o elemento sobre o qual o ponteiro estava de fato.
Escolher a coordenada correta importa: use clientX/clientY para posicionar algo fixo na janela, pageX/pageY para posicionar algo dentro de conteúdo com rolagem, e offsetX/offsetY (ou subtraia getBoundingClientRect()) para desenhar dentro de um elemento específico como um canvas.
Implementando Handlers Básicos de Eventos de Mouse
Exemplo: Criando um Botão Clicável
Considere um botão que muda de cor toda vez que é clicado. Essa interação simples pode ser implementada usando o evento click.
<div>
<button id="colorButton">Click me to change color</button>
</div>
<script>
document.getElementById('colorButton').addEventListener('click', function() {
this.style.backgroundColor = this.style.backgroundColor === 'red' ? 'blue' : 'red';
});
</script>Neste exemplo, cada clique altera a cor de fundo do botão entre vermelho e azul. Isso não apenas melhora o feedback visual, mas também apresenta aos usuários mudanças dinâmicas por meio de interações simples.
Interação Avançada: Evento de Duplo Clique
Um evento de duplo clique pode ser usado para alternar o tamanho do texto, fornecendo um método rápido para ampliar o conteúdo.
<div>
<p id="text">Double-click me to toggle text size.</p>
</div>
<script>
document.getElementById('text').addEventListener('dblclick', function() {
this.style.fontSize = this.style.fontSize === '16px' ? '32px' : '16px';
});
</script>Este script aumenta o tamanho da fonte no primeiro duplo clique e o redefine no próximo, tornando-se um recurso prático para melhorar a legibilidade.
mouseenter / mouseleave vs. mouseover / mouseout
Esta é a armadilha mais comum com eventos de mouse. mouseover/mouseout propagam: quando o ponteiro cruza para um elemento filho, mouseout dispara no elemento pai e mouseover dispara novamente — por isso um handler em um contêiner com filhos dispara repetidamente. mouseenter/mouseleave não propagam e disparam apenas uma vez quando o ponteiro cruza a borda externa do elemento, ignorando o movimento entre filhos.
Regra geral: para um efeito de hover simples em um único elemento, prefira mouseenter/mouseleave. Use mouseover/mouseout apenas quando quiser detectar deliberadamente a entrada em elementos filhos (por exemplo, com delegação de eventos).
Exemplo: Destaque de Texto ao Passar o Mouse
<div>
<p id="hoverText">Hover over me to highlight.</p>
</div>
<script>
document.getElementById('hoverText').addEventListener('mouseenter', function() {
this.style.color = 'green';
});
document.getElementById('hoverText').addEventListener('mouseleave', function() {
this.style.color = 'black';
});
</script>Este exemplo melhora a interação do usuário ao mudar a cor do texto para verde quando o mouse passa sobre ele e retorná-la para preto quando o mouse sai, demonstrando o uso de mouseenter e mouseleave.
Aproveitando o Movimento do Mouse
Exemplo: Exibir Coordenadas do Mouse
Neste exemplo, as coordenadas do mouse são exibidas em tempo real à medida que o usuário move o mouse sobre o texto. Esse uso do evento mousemove é excelente para aplicações que precisam rastrear a posição do mouse. Observe que mousemove pode disparar dezenas de vezes por segundo — mantenha seu handler eficiente e evite operações pesadas no DOM dentro dele.
<div>
<p id="mousePosition" style="height: 100px; background-color: orangered">
Hover here to track your mouse position!
</p>
</div>
<script>
document.getElementById('mousePosition').addEventListener('mousemove', function(event) {
this.textContent = `Mouse Position - X: ${event.clientX}, Y: ${event.clientY}`;
});
</script>Este exemplo exibe as coordenadas x e y do cursor do mouse enquanto ele se move sobre o texto, fornecendo feedback em tempo real ao usuário.
Aplicações Avançadas
Implementando um Menu de Contexto Personalizado
Menus de contexto personalizados são uma ótima maneira de melhorar como os usuários interagem com as opções de clique com o botão direito no seu site. A chave é event.preventDefault() dentro do handler de contextmenu, que impede o menu nativo do navegador de aparecer para que o seu possa tomar o lugar.
<div>
<p>Right Click anywhere to see a customized context menu other than the default one in the browser!</p>
</div>
<div>
<div id="contextMenu" style="display:none; position:absolute; background-color:white; border:1px solid black; padding:10px;">
<ul>
<li>Refresh</li>
<li>Save Page</li>
<li>Search</li>
</ul>
</div>
</div>
<script>
document.addEventListener('contextmenu', function(event) {
event.preventDefault();
let menu = document.getElementById('contextMenu');
menu.style.display = 'block';
menu.style.left = `${event.clientX}px`;
menu.style.top = `${event.clientY}px`;
});
document.addEventListener('click', function(event) {
const menu = document.getElementById('contextMenu');
if (!menu.contains(event.target)) {
menu.style.display = 'none';
}
});
</script>Este código JavaScript faz duas coisas principais:
- Quando você clica com o botão direito:
- Ele impede o menu de clique com o botão direito normal de aparecer (
event.preventDefault()). - Ele exibe um menu personalizado onde você clicou com o botão direito, posicionado com
event.clientX/event.clientY.
- Ele impede o menu de clique com o botão direito normal de aparecer (
- Quando você clica em qualquer lugar:
- Ele oculta o menu personalizado para que ele não permaneça na tela.
Criando Gráficos Interativos com HTML Canvas
Esta aplicação de desenho interativa permite que os usuários desenhem em um canvas usando o mouse. O evento mousemove rastreia o movimento do mouse para desenhar linhas, ideal para aplicações gráficas simples ou jogos.
Exemplo: Aplicação de Desenho Simples
<div>
<p>Start drawing in the box below and see the result!</p>
</div>
<div>
<canvas id="drawingCanvas" width="400" height="300" style="border:1px solid #000;"></canvas>
</div>
<script>
const canvas = document.getElementById('drawingCanvas');
const ctx = canvas.getContext('2d');
let drawing = false;
canvas.addEventListener('mousedown', () => {
drawing = true;
ctx.beginPath();
});
canvas.addEventListener('mouseup', () => drawing = false);
canvas.addEventListener('mouseout', () => drawing = false);
canvas.addEventListener('mousemove', function(event) {
if (drawing) {
const rect = canvas.getBoundingClientRect();
ctx.lineTo(event.clientX - rect.left, event.clientY - rect.top);
ctx.stroke();
}
});
</script>Este código configura uma área de desenho em uma página web usando um elemento <canvas>:
- JavaScript para Desenho:
- Ele começa obtendo o canvas e seu contexto de desenho, que é usado para desenhar.
- O desenho começa quando você pressiona o mouse sobre o canvas e para quando você solta o mouse ou o move para fora do canvas.
- Enquanto você move o mouse sobre o canvas com o botão pressionado, ele desenha linhas seguindo o cursor do mouse.
Implementando Recursos de Arrastar e Soltar
O padrão clássico usa três eventos: mousedown no elemento para iniciar o arrasto, mousemove no documento para seguir o ponteiro (escutar no documento, e não no elemento, significa que o arrasto continua funcionando mesmo que o ponteiro se mova mais rápido do que a caixa) e mouseup para parar.
<div>
<div id="draggable" style="width: 100px; height: 100px; background: blue; position: absolute; color: white; padding: 10px"> Drag me!
</div>
</div>
<script>
const draggable = document.getElementById('draggable');
let active = false;
let currentX;
let currentY;
let initialX;
let initialY;
draggable.addEventListener('mousedown', function(event) {
active = true;
const rect = draggable.getBoundingClientRect();
initialX = event.clientX - rect.left;
initialY = event.clientY - rect.top;
});
document.addEventListener('mouseup', function() {
active = false;
});
document.addEventListener('mousemove', function(event) {
if (active) {
currentX = event.clientX - initialX;
currentY = event.clientY - initialY;
draggable.style.left = currentX + 'px';
draggable.style.top = currentY + 'px';
}
});
</script>Este código cria um quadrado azul arrastável simples em uma página web:
- JavaScript para Arrastar:
- O quadrado pode ser movido clicando e segurando o mouse sobre ele. Quando você pressiona o mouse (
mousedown), ele registra onde você o agarrou e prepara o quadrado para se mover. - Quando você solta o mouse (
mouseup), o quadrado para de se mover. - Enquanto mantém o mouse pressionado, se você mover o mouse (
mousemove), o quadrado segue o ponteiro pela tela, se movendo para onde você o arrasta.
- O quadrado pode ser movido clicando e segurando o mouse sobre ele. Quando você pressiona o mouse (
Melhorando a Usabilidade de Formulários
Melhorar a usabilidade de formulários fornecendo elementos interativos, como ícones de ajuda, pode melhorar muito a experiência do usuário. Este exemplo mostra uma maneira simples e eficaz de adicionar texto de ajuda dinâmico a campos de formulário.
<div>
<p style="font-weight: bold;">Hover your mouse on the icon!</p>
<label for="password">Password:</label>
<input type="password" id="password" />
<span id="helpIcon" style="cursor: help;">ⓘ</span>
<div id="helpText" style="display:none; margin-top: 10px;">Use 8 or more characters with a mix of letters, numbers & symbols.</div>
</div>
<script>
document.getElementById('helpIcon').addEventListener('mouseover', function() {
document.getElementById('helpText').style.display = 'block';
});
document.getElementById('helpIcon').addEventListener('mouseout', function() {
document.getElementById('helpText').style.display = 'none';
});
</script>Este código fornece um recurso de ajuda para um campo de entrada de senha em uma página web:
- Campo de Senha e Ícone de Ajuda: Há um rótulo, um campo de entrada de senha e um ícone de ajuda ao lado do campo.
- JavaScript para Exibir Texto de Ajuda:
- Quando você move o mouse sobre o ícone (
mouseover), uma mensagem oculta logo abaixo aparece com dicas sobre como criar uma senha forte. - Quando você afasta o mouse do ícone (
mouseout), a mensagem desaparece.
- Quando você move o mouse sobre o ícone (
Nota sobre Acessibilidade
Os eventos de mouse disparam apenas para usuários de ponteiro. Usuários de teclado, usuários de leitores de tela e dispositivos de toque não acionarão handlers de mouseover, mousemove ou clique com o botão direito. Para qualquer coisa importante, combine handlers de mouse com seus equivalentes acessíveis:
- Adicione listeners de
focus/blurjunto commouseenter/mouseleavepara que o efeito também funcione quando o elemento for acessado via Tab. - Adicione
keydown(Enter/Space) junto comclickpara widgets personalizados que não são botões nativos. - Nunca oculte conteúdo essencial apenas por hover.
Consulte Considerações de acessibilidade do DOM para o panorama completo.
Conclusão
Os eventos de mouse em JavaScript oferecem um conjunto robusto de ferramentas para criar experiências web interativas — desde um simples click até menus de contexto personalizados, desenho em canvas e arrastar e soltar. As chaves para usá-los bem são: escolha o evento correto (mouseenter vs mouseover), leia a coordenada correta (clientX vs pageX vs offsetX) do objeto de evento, mantenha os handlers de mousemove leves e sempre forneça uma alternativa acessível pelo teclado. Com esses hábitos, os eventos de mouse se tornam uma base confiável para interfaces envolventes.