Manejo de Eventos en el DOM
Aprende el manejo de eventos en el DOM con JavaScript: addEventListener, removeEventListener, el objeto event, preventDefault, propagación de eventos y delegación de eventos.
Introducción a los Eventos de JavaScript
Los eventos de JavaScript son acciones u ocurrencias que suceden en el navegador — un clic, una pulsación de tecla, una página que termina de cargarse — que tu código puede detectar y a las que puede responder. Reaccionar a los eventos es lo que convierte una página estática en una aplicación interactiva.
Este capítulo cubre las tres formas de registrar manejadores de eventos, los tipos de eventos más comunes, el objeto event que recibe cada manejador, cómo viajan los eventos a través del DOM (propagación y captura), y los patrones que mantienen las páginas con muchos eventos eficientes y libres de fugas de memoria.
Tres Formas de Manejar Eventos
Antes de ver eventos específicos, conviene saber que existen tres maneras distintas de adjuntar un manejador. Se enumeran de la más antigua a la más flexible.
| Enfoque | Ejemplo | ¿Múltiples manejadores? | Recomendado |
|---|---|---|---|
| Atributo HTML en línea | <button onclick="doX()"> | No | No — mezcla marcado y lógica |
| Propiedad del DOM | element.onclick = fn | No (el último prevalece) | Solo para casos simples |
addEventListener() | element.addEventListener("click", fn) | Sí | Sí — el estándar 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 manejadores se ejecutan al hacer clic. Si asignas btn.onclick una segunda vez, la primera asignación se pierde silenciosamente — que es la razón principal por la que se prefiere addEventListener(). El resto de este capítulo usa addEventListener().
Eventos Comunes en JavaScript
Evento Click
El evento click se dispara cuando el usuario presiona y suelta el botón principal del ratón (o toca, en dispositivos táctiles) sobre un elemento. Es el evento más utilizado.
<button id="clickButton">Click Me</button>
<script>
document.getElementById("clickButton").addEventListener("click", function () {
alert("Button was clicked!");
});
</script>En este ejemplo, se agrega un escuchador de eventos a un botón con el ID clickButton. Cuando se hace clic en el botón, aparecerá un cuadro de alerta con el mensaje "Button was clicked!".
Evento Mouseover
El evento mouseover se dispara cuando el puntero del ratón se mueve sobre un elemento. (Su contraparte, mouseout, se dispara cuando el puntero lo abandona.)
<p id="mouseoverText">Hover over me!</p>
<script>
document.getElementById("mouseoverText").addEventListener("mouseover", function () {
this.style.color = "red";
});
</script>En este ejemplo, se agrega un escuchador de eventos a un párrafo con el ID mouseoverText. Cuando el ratón pasa sobre el párrafo, el color de su texto cambia a rojo.
Evento Keydown
El evento keydown se dispara cuando el usuario presiona una tecla mientras un elemento tiene el foco. El manejador recibe un objeto event cuya propiedad event.key contiene el valor de la 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>En este ejemplo, se agrega un escuchador de eventos a un campo de entrada con el ID inputField. Cuando se presiona una tecla mientras el campo de entrada tiene el foco, la tecla presionada se muestra en un cuadro de alerta.
El Objeto Event
Cada manejador es llamado con un argumento: el objeto event. Describe lo que ocurrió y expone métodos para controlar el evento. Los miembros más útiles son:
event.target— el elemento en el que el evento se originó (por ejemplo, el botón exacto que se hizo clic).event.currentTarget— el elemento al que está adjunto el escuchador. Dentro de una función regular es igual athis.event.type— el nombre del evento, como"click".event.preventDefault()— cancela la acción predeterminada del navegador (seguir un enlace, enviar un formulario).event.stopPropagation()— impide que el evento continúe propagándose por el 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>Aquí preventDefault() evita que la página navegue, de modo que puedes ejecutar tu propia lógica en su lugar — un patrón común en aplicaciones de página única y validación de formularios personalizada.
Dentro de una función flecha, this no se reasigna al elemento. Usa event.currentTarget (o una function normal) cuando necesites una referencia al elemento en el que está el escuchador. Consulta funciones flecha revisadas para saber por qué.
Agregar Escuchadores de Eventos
El Método addEventListener()
El método addEventListener() adjunta un manejador de eventos a un elemento sin sobrescribir los manejadores existentes. Esto significa que puedes adjuntar múltiples escuchadores — incluso para el mismo tipo de evento — a un solo elemento. Su firma es element.addEventListener(type, handler, options), donde options puede ajustar el comportamiento (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>En este ejemplo, se agregan dos escuchadores de eventos al botón con el ID multiEventButton. Un escuchador muestra una alerta cuando se hace clic en el botón, y el otro cambia el color de fondo del botón cuando el ratón pasa sobre él.
Usa addEventListener() para adjuntar múltiples escuchadores de eventos al mismo elemento sin sobrescribir los manejadores existentes.
Eliminar Escuchadores de Eventos
El Método removeEventListener()
El método removeEventListener() desconecta un manejador que fue adjuntado con addEventListener(). La condición: debes pasar la misma referencia de función exacta que agregaste, por eso se requieren funciones con nombre para poder eliminar un escuchador más adelante.
<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>En este ejemplo, se agrega al botón con el ID removeEventButton un escuchador de eventos que muestra una alerta. Se agrega otro escuchador de eventos para eliminar el escuchador de alerta después del primer clic. Ten en cuenta que removeEventListener requiere una referencia al mismo objeto de función exacto que se usó en addEventListener. Por eso las funciones anónimas no pueden eliminarse más tarde — cada declaración crea un objeto de función nuevo y distinto.
Aprovecha la delegación de eventos para mejorar el rendimiento, especialmente cuando se trabaja con un gran número de elementos hijo.
Propagación y Delegación de Eventos
Cuando un evento se dispara en un elemento, no se detiene allí. Por defecto viaja en dos fases: primero la captura (desde la cima del DOM hasta el objetivo) y luego la propagación (desde el objetivo de regreso hasta la raíz). La mayoría de los manejadores se ejecutan durante la fase de propagación, por eso un clic en un botón también llega a un escuchador de clic en su <div> padre.
Esta propagación habilita la delegación de eventos: en lugar de adjuntar un escuchador a cada elemento hijo, se adjunta un escuchador a un padre común y se lee event.target para saber en qué hijo se hizo clic realmente.
<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>Un solo escuchador en <ul> maneja cada <li>, incluidos los que se agreguen a la lista más adelante — mucho más eficiente que conectar cada elemento individualmente. Para una mirada más profunda a las fases y stopPropagation(), consulta propagación y captura.
Buenas Prácticas
Usa la Delegación de Eventos
Agrega un único escuchador de eventos a un elemento padre para gestionar los eventos de todos los elementos hijo. Esto mejora el rendimiento y reduce el número de escuchadores de eventos.
Evita Funciones Anónimas como Manejadores de Eventos
Usar funciones con nombre como manejadores de eventos facilita eliminarlos más adelante y mejora la legibilidad del código.
Limpia los Escuchadores de Eventos
Asegúrate de que los escuchadores de eventos se eliminen cuando ya no sean necesarios para evitar fugas de memoria y mejorar el rendimiento.
Minimiza el Número de Escuchadores de Eventos
Adjunta escuchadores de eventos a elementos de nivel superior en lugar de a numerosos elementos individuales para reducir el uso de memoria y mejorar el rendimiento.
Usa la Opción once en addEventListener
Utiliza la opción once para eliminar automáticamente el escuchador de eventos después de que se active una vez, evitando posibles fugas de memoria.
button.addEventListener("click", function handler() {
console.log("Triggered once");
}, { once: true });Usa preventDefault y stopPropagation de Forma Apropiada
Usa event.preventDefault() y event.stopPropagation() con criterio para controlar el comportamiento de los eventos sin interferir con otros manejadores.
Usa Debounce o Throttle en los Manejadores de Eventos
Utiliza técnicas de debounce o throttle para optimizar el rendimiento de los manejadores de eventos que se activan con frecuencia, como los eventos de scroll o resize.
Conclusión
Dominar los eventos de JavaScript es fundamental para crear aplicaciones web dinámicas e interactivas. Al entender cómo usar eventos como click, mouseover y keydown, y cómo agregar y eliminar escuchadores de eventos con addEventListener() y removeEventListener(), puedes mejorar significativamente las interacciones de los usuarios en tus páginas web.