Conceptos básicos de eventos de ratón en JavaScript
Aprende los eventos de ratón en JavaScript: click, dblclick, mousedown, mouseup, mousemove, mouseover vs mouseenter y contextmenu. Incluye el objeto MouseEvent (clientX, pageX, offsetX, button) con ejemplos de arrastrar y soltar y canvas.
Introducción
En JavaScript, los eventos de ratón permiten que tu página responda a lo que el usuario hace con el puntero: hacer clic en un botón, pasar el ratón sobre un enlace, arrastrar un elemento o hacer clic derecho para abrir un menú. Conectar scripts a estos eventos es lo que transforma un documento estático en una interfaz interactiva.
Esta guía cubre el conjunto completo de eventos básicos de ratón, los datos que obtienes del objeto de evento (qué botón se pulsó, dónde está el puntero), la diferencia importante entre mouseover y mouseenter, y varios ejemplos ejecutables: un alternador de colores, un menú contextual personalizado, un canvas de dibujo y arrastrar y soltar. Los eventos de ratón forman parte de la familia más amplia de eventos del navegador; si eres nuevo en el manejo de manejadores, lee primero Manejo de eventos en el DOM.
Comprender los eventos de ratón en JavaScript
Un evento de ratón es una señal que el navegador emite cuando el usuario interactúa con la página usando un dispositivo señalador. Para responder a él, debes registrar un listener con addEventListener('eventName', handler). El manejador recibe un objeto MouseEvent que describe lo que ocurrió.
Eventos de ratón principales
| Evento | Se dispara cuando… |
|---|---|
click | Se presiona y suelta un botón sobre el mismo elemento. |
dblclick | Se hace clic dos veces sobre el elemento en rápida sucesión. |
mousedown | Se presiona un botón del ratón. |
mouseup | Se suelta un botón del ratón. |
mousemove | El puntero se mueve mientras está sobre el elemento (se dispara muchas veces). |
mouseover | El puntero entra en el elemento o en uno de sus hijos (burbujea). |
mouseout | El puntero sale del elemento o de uno de sus hijos (burbujea). |
mouseenter | El puntero entra en el elemento (no burbujea). |
mouseleave | El puntero sale del elemento (no burbujea). |
contextmenu | Se hace clic con el botón derecho, antes de que se abra el menú nativo. |
Un click completo es en realidad tres eventos en orden: mousedown → mouseup → click. Conocer la secuencia ayuda cuando un evento parece "absorber" a otro.
Leer el objeto MouseEvent
Cada manejador de ratón recibe un objeto de evento con propiedades útiles:
event.clientX/event.clientY— posición del puntero relativa al viewport (la ventana visible).event.pageX/event.pageY— posición relativa al documento completo, incluyendo el desplazamiento.event.offsetX/event.offsetY— posición relativa al cuadro del elemento objetivo.event.button— qué botón:0= izquierdo,1= central,2= derecho.event.ctrlKey/event.shiftKey/event.altKey/event.metaKey—truesi esa tecla modificadora estaba presionada durante el evento.event.target— el elemento sobre el que estaba realmente el puntero.
Elegir la coordenada correcta importa: usa clientX/clientY para posicionar algo fijo en la ventana, pageX/pageY para posicionar algo dentro de contenido con desplazamiento, y offsetX/offsetY (o resta getBoundingClientRect()) para dibujar dentro de un elemento específico como un canvas.
Implementar manejadores básicos de eventos de ratón
Ejemplo: crear un botón interactivo
Considera un botón que cambia de color cada vez que se hace clic en él. Esta interacción simple se puede implementar usando el 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>En este ejemplo, cada clic cambia el color de fondo del botón entre rojo y azul. Esto no solo mejora la retroalimentación visual, sino que también introduce a los usuarios a los cambios dinámicos mediante interacciones simples.
Interacción avanzada: evento de doble clic
El evento de doble clic se puede usar para alternar el tamaño del texto, proporcionando un método rápido para hacer zoom en el contenido.
<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 el tamaño de fuente con el primer doble clic y lo restablece en el siguiente, convirtiéndolo en una función práctica para mejorar la legibilidad.
mouseenter / mouseleave vs. mouseover / mouseout
Este es el error más común con los eventos de ratón. mouseover/mouseout burbujean: cuando el puntero cruza hacia un elemento hijo, mouseout se dispara en el padre y mouseover se dispara de nuevo, por lo que un manejador en un contenedor con hijos se dispara repetidamente. mouseenter/mouseleave no burbujean y se disparan solo una vez cuando el puntero cruza el límite exterior del elemento, ignorando el movimiento entre hijos.
Regla general: para un efecto de hover simple en un elemento, prefiere mouseenter/mouseleave. Usa mouseover/mouseout solo cuando deliberadamente quieres detectar la entrada en elementos hijos (por ejemplo, con delegación de eventos).
Ejemplo: resaltado de texto al pasar el ratón
<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 ejemplo mejora la interacción del usuario cambiando el color del texto a verde cuando el ratón pasa por encima y volviéndolo a negro cuando el ratón se aleja, demostrando el uso de mouseenter y mouseleave.
Aprovechar el movimiento del ratón
Ejemplo: mostrar las coordenadas del ratón
En este ejemplo, las coordenadas del ratón se muestran en tiempo real mientras el usuario mueve el ratón sobre el texto. Este uso del evento mousemove es excelente para aplicaciones que requieren rastrear la posición del ratón. Ten en cuenta que mousemove puede dispararse decenas de veces por segundo: mantén su manejador liviano y evita operaciones pesadas en el DOM dentro de él.
<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 ejemplo muestra las coordenadas x e y del cursor del ratón a medida que se mueve sobre el texto, proporcionando retroalimentación en tiempo real al usuario.
Aplicaciones avanzadas
Implementar un menú contextual personalizado
Los menús contextuales personalizados son una excelente manera de mejorar cómo los usuarios interactúan con las opciones del clic derecho en tu sitio. La clave es event.preventDefault() dentro del manejador contextmenu, lo que detiene el menú integrado del navegador para que el tuyo pueda ocupar su 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 hace dos cosas principales:
- Al hacer clic derecho:
- Detiene la aparición del menú normal de clic derecho (
event.preventDefault()). - Muestra un menú personalizado donde hiciste clic derecho, posicionado con
event.clientX/event.clientY.
- Detiene la aparición del menú normal de clic derecho (
- Al hacer clic en cualquier lugar:
- Oculta el menú personalizado para que no permanezca en la pantalla.
Crear gráficos interactivos con HTML Canvas
Esta aplicación de dibujo interactiva permite a los usuarios dibujar en un canvas usando su ratón. El evento mousemove rastrea el movimiento del ratón para trazar líneas, ideal para aplicaciones gráficas simples o juegos.
Ejemplo: aplicación de dibujo simple
<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 un área de dibujo en una página web usando un elemento <canvas>:
- JavaScript para dibujar:
- Comienza obteniendo el canvas y su contexto de dibujo, que se usa para dibujar.
- El dibujo comienza cuando presionas el botón del ratón sobre el canvas y se detiene cuando sueltas el ratón o lo mueves fuera del canvas.
- Mientras mueves el ratón sobre el canvas con el botón del ratón presionado, traza líneas siguiendo el cursor del ratón.
Implementar funciones de arrastrar y soltar
El patrón clásico usa tres eventos: mousedown en el elemento para iniciar el arrastre, mousemove en el documento para seguir el puntero (escuchar en el documento, no en el elemento, significa que el arrastre sigue funcionando aunque el puntero se mueva más rápido que el cuadro), y mouseup para detenerlo.
<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 crea un cuadrado azul arrastrable simple en una página web:
- JavaScript para arrastrar:
- El cuadrado se puede mover haciendo clic y manteniendo presionado el ratón sobre él. Cuando presionas el botón del ratón (
mousedown), registra dónde lo agarraste y prepara el cuadrado para moverse. - Cuando sueltas el ratón (
mouseup), el cuadrado deja de moverse. - Mientras mantienes presionado el botón del ratón, si mueves el ratón (
mousemove), el cuadrado sigue el puntero por la pantalla, moviéndose a donde lo arrastres.
- El cuadrado se puede mover haciendo clic y manteniendo presionado el ratón sobre él. Cuando presionas el botón del ratón (
Mejorar la usabilidad de formularios
Mejorar la usabilidad de los formularios proporcionando elementos interactivos como iconos de ayuda puede mejorar enormemente la experiencia del usuario. Este ejemplo muestra una forma simple y efectiva de añadir texto de ayuda dinámico a los campos del formulario.
<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 proporciona una función de ayuda para un campo de entrada de contraseña en una página web:
- Campo de contraseña e icono de ayuda: hay una etiqueta, una entrada de contraseña y un icono de ayuda junto al campo.
- JavaScript para mostrar el texto de ayuda:
- Cuando mueves el ratón sobre el icono (
mouseover), aparece un mensaje oculto justo debajo con consejos para crear una contraseña segura. - Cuando alejas el ratón del icono (
mouseout), el mensaje desaparece.
- Cuando mueves el ratón sobre el icono (
Nota sobre accesibilidad
Los eventos de ratón solo se disparan para usuarios con puntero. Los usuarios de teclado, los usuarios de lectores de pantalla y los dispositivos táctiles no activarán los manejadores de mouseover, mousemove ni clic derecho. Para cualquier cosa importante, combina los manejadores de ratón con sus equivalentes accesibles:
- Añade listeners de
focus/blurjunto amouseenter/mouseleavepara que el efecto también funcione cuando se accede al elemento mediante tabulación. - Añade
keydown(Enter/Espacio) junto aclickpara widgets personalizados que no sean botones nativos. - Nunca ocultes contenido esencial solo detrás del hover.
Consulta Consideraciones de accesibilidad del DOM para obtener una visión completa.
Conclusión
Los eventos de ratón en JavaScript ofrecen un conjunto robusto de herramientas para crear experiencias web interactivas, desde un simple click hasta menús contextuales personalizados, dibujo en canvas y arrastrar y soltar. Las claves para usarlos bien son: elegir el evento correcto (mouseenter vs mouseover), leer la coordenada correcta (clientX vs pageX vs offsetX) del objeto de evento, mantener los manejadores de mousemove ligeros y siempre proporcionar una alternativa accesible para el teclado. Con esos hábitos, los eventos de ratón se convierten en una base confiable para interfaces atractivas.