¿Qué es un evento en el DOM? Ejemplos!

Un evento en el DOM es una acción del usuario o del navegador que permite ejecutar código JavaScript para responder a esa interacción. En esta guía vas a ver qué es un evento y para qué sirve, cómo crearlos con addEventListener, cómo funciona el objeto Event y ejemplos simples para entender todo el proceso de forma práctica.

que es un evento en el dom

1. ¿Qué es un evento en el DOM?

Un evento en el DOM es una notificación que el navegador envía cuando algo ocurre dentro del documento HTML, ya sea una acción del usuario o un cambio interno del sistema.
Dicho de otra forma: un evento es una señal que indica que algo pasó, como un clic, una pulsación de tecla, el envío de un formulario, o incluso la carga completa de la página.

CONCEPTOS FUNDAMENTALES

  • El DOM (Document Object Model) representa la estructura del documento HTML como un árbol de nodos.
  • Cuando el usuario interactúa con la página (por ejemplo, hace clic en un botón), el navegador dispara un evento asociado a ese nodo.
  • JavaScript puede «escuchar» esos eventos y responder ejecutando código específico.
    A esa respuesta se le llama manejador de evento o event handler.

🚀Ampliemos esta definición…..

1.1. ¿Cómo funcionan los eventos en el DOM y JavaScript?

Como dijimos, los eventos en el DOM son mecanismos internos del navegador que permiten detectar e interactuar con las acciones del usuario o con ciertos cambios en la página.
Cuando una persona realiza una acción, como hacer clic en un botón, presionar una tecla o enviar un formulario, el navegador genera un evento y lo asocia al elemento del DOM donde ocurrió.

El código JavaScript, que ya fue cargado en el navegador junto con el HTML y el CSS, escucha esos eventos mediante funciones conocidas como manejadores de eventos o event listeners.
Cuando el evento sucede, el navegador ejecuta la función JavaScript correspondiente, sin necesidad de comunicarse con el servidor.

POR EJEMPLO…. si se hace clic en un botón, el evento "click" se dispara dentro del navegador, y el código JavaScript que lo escucha se ejecuta inmediatamente en el dispositivo del usuario.
💡Solo si ese código incluye una acción para consultar o enviar datos al servidor (por ejemplo, mediante fetch()), se produce una comunicación externa.

En resumen, los eventos funcionan completamente del lado del cliente:
el navegador los detecta, los gestiona y ejecuta el JavaScript asociado, haciendo que la página responda de manera dinámica e interactiva a las acciones del usuario.

1.2. Ejemplo de un evento de click.

Supongamos que tenemos una estructura básica donde existe un botón en HTML y un archivo JavaScript asociado a ese documento.
Cuando esta página se carga en un navegador (por ejemplo, Google Chrome), el navegador interpreta el HTML, aplica los estilos CSS y ejecuta el JavaScript vinculado.

Una vez que la página está visible, si el usuario realiza una acción —como hacer clic en el botón—, el navegador detecta esa interacción y genera un evento del tipo "click".
Ese evento es manejado internamente por el navegador, que lo asocia al elemento sobre el que ocurrió (en este caso, el botón).
Luego, el navegador ejecuta la función JavaScript que está escuchando ese evento, produciendo la acción que fue definida por el programador.

En otras palabras, el evento "click" actúa como un disparador que hace que el navegador ejecute el código JavaScript asociado al botón, sin necesidad de comunicarse con el servidor.

HTML

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Ejemplo de Evento en el DOM</title>
</head>
<body>
  <button id="miBoton">Hacer clic aquí</button>

  <script src="script.js"></script>
</body>
</html>Lenguaje del código: HTML, XML (xml)

JavaScript (script.js)

// Paso 1: Seleccionar el elemento del DOM
const boton = document.getElementById('miBoton');

// Paso 2: Asociar un escuchador de evento "click"
boton.addEventListener('click', () => {
  alert('¡Has hecho clic en el botón!');
});
Lenguaje del código: JavaScript (javascript)

Explicación:

  1. El navegador carga el HTML
    Construye el árbol del DOM y detecta la etiqueta <script> que vincula el archivo script.js.
  2. El navegador ejecuta el JavaScript
    Se lee el contenido de script.js y se guarda en memoria la instrucción que dice:
    “Cuando el usuario haga clic en el botón con ID miBoton, ejecutá esta función”.
  3. El usuario interactúa con la página
    Al hacer clic en el botón, el navegador genera internamente un evento DOM del tipo "click".
  4. El navegador ejecuta el código asociado
    Detecta que ese botón tiene un listener para el evento "click", y ejecuta la función que muestra la alerta.
  5. El resultado visible
    En ese momento, aparece el mensaje en pantalla: ¡Has hecho clic en el botón!

💡 EN PALABRAS SENCILLAS: El evento "click" es como un mensaje interno que el navegador genera cuando el usuario interactúa con un elemento. Ese mensaje activa el código JavaScript asociado, que se ejecuta directamente en el navegador, sin necesidad de comunicarse con el servidor.

2. El método addEventListener().

2.1. ¿Qué es addEventListener()?

addEventListener() es un método del DOM que se utiliza para registrar (o “escuchar”) un evento en un elemento HTML.

En palabras simples: Sirve para indicarle al navegador que ejecute una función específica cuando ocurra una determinada acción del usuario (como un clic, un movimiento del mouse, una tecla presionada, etc.).

2.2. Sintaxis de addEventListener()

La sintaxis fundamental de addEventListener() es crucial para registrar una función que responderá a una interacción específica del usuario o del navegador.

elemento.addEventListener('nombreDelEvento', funcionManejadora, [opciones]);Lenguaje del código: JavaScript (javascript)

Desglose de la sintaxis:

  1. elemento
    • Es el objeto DOM (Document Object Model) al que queremos adjuntar el listener. Debe ser un elemento válido que has seleccionado previamente (ejemplo: un botón, un <div>, o el objeto document).
  2. 'nombreDelEvento'
    • Es una cadena de texto que especifica el tipo de evento que estamos esperando. Siempre debe estar en minúsculas.
Ejemplo de Nombre Descripción
'click' El usuario hizo clic en el elemento.
'input' El valor de un campo de formulario ha cambiado.
'mouseover' El puntero del ratón se mueve sobre el elemento.
'submit' Se intenta enviar un formulario.
'load' El navegador terminó de cargar un recurso (ej. una imagen).
  1. funcionManejadora
    • Es la función (callback) que se ejecutará cada vez que se dispare el evento. Esta función recibe automáticamente el Objeto Event como su primer argumento.
  2. [opciones]
    • Este tercer argumento es un objeto o un valor booleano (para la captura) que permite configurar el comportamiento del listener. El uso más común es para controlar el flujo de eventos:
      • { capture: true }: El listener se dispara en la fase de Captura (antes de que el evento llegue al objetivo).
      • { once: true }: El listener se disparará solo una vez y luego se eliminará automáticamente.
      • { passive: true }: Se usa para mejorar el rendimiento, especialmente con eventos como 'scroll', indicando que el manejador no llamará a preventDefault().

2.3. Ejemplo básico: Escuchar un clic en un botón

Supongamos que tenemos este HTML:

<button id="saludar">Hacer clic aquí</button>Lenguaje del código: HTML, XML (xml)

Y este JavaScript:

// Paso 1: Seleccionamos el botón del DOM
const boton = document.getElementById('saludar');

// Paso 2: Definimos la función que queremos ejecutar cuando ocurra el evento
function mostrarMensaje() {
  alert('¡Hola! Hiciste clic en el botón.');
}

// Paso 3: Asociamos el evento al botón con addEventListener
boton.addEventListener('click', mostrarMensaje);Lenguaje del código: JavaScript (javascript)

Explicación:

  1. document.getElementById('saludar')
    • Seleccionamos el botón del DOM para poder interactuar con él desde JavaScript.
  2. Definimos la función mostrarMensaje()
    • Esta función contiene el código que queremos ejecutar cuando se haga clic.
  3. boton.addEventListener('click', mostrarMensaje)
    • Le decimos al navegador: “Cuando el usuario haga clic en este botón, ejecutá la función mostrarMensaje.”

De esta forma, el código permanece limpio y estructurado, sin mezclar HTML con JavaScript.

3. El modelo de eventos del navegador (Event Model)

3.1. ¿Qué es el modelo de eventos del navegador?

Cuando ocurre un evento en el DOM (por ejemplo, un clic en un botón), el navegador sigue un proceso en tres fases para determinar qué elementos reciben el evento y en qué orden.
Estas tres fases son:

  1. Fase de captura (Capturing Phase)
    • El evento baja desde el objeto global window, pasando por todos los elementos padres, hasta llegar al elemento objetivo.
  2. Fase objetivo (Target Phase)
    • El evento alcanza el elemento donde realmente ocurrió la acción (por ejemplo, el botón que fue clickeado).
  3. Fase de burbuja (Bubbling Phase)
    • Luego, el evento “burbujea” hacia arriba, desde el elemento objetivo de nuevo hasta window, pasando otra vez por todos los elementos padres.

3.2. ¿Qué es “Bubbling”?

El bubbling (burbujeo) es el comportamiento por defecto en la mayoría de los eventos.
Significa que, después de que el evento ocurre en el elemento objetivo, ese mismo evento se propaga hacia arriba por la jerarquía del DOM, afectando a los elementos ancestros que también tengan un escuchador (listener) para ese evento.

¿Qué significa listener? Como ya explicamos en el punto sobre addEventListener(), un listener es simplemente una función que “escucha” un evento en un elemento del DOM. Se ejecuta automáticamente cuando ocurre un evento (por ejemplo: click, mouseover, keydown, scroll, submit, etc.) en un elemento específico.

3.3. ¿Cómo controlar en qué fase se ejecuta un listener?

Cuando agregás un escuchador de eventos con addEventListener, podés indicar si querés que se ejecute durante la fase de captura o durante la fase de burbuja.

¿Cómo? 👇

// En la parte opcional de la sintaxis (ver punto 2.2.) podemos colocar las siguientes indicaciones

element.addEventListener('click', function, { capture: true }); // Captura
element.addEventListener('click', function, false);             // Burbuja (por defecto)Lenguaje del código: PHP (php)

3.4. Ejemplo práctico: Captura y burbujeo en acción

Supongamos que tenemos esta estructura HTML:

<div id="contenedor">
  <button id="boton">Hacer clic aquí</button>
</div>Lenguaje del código: HTML, XML (xml)

Y este código JavaScript asociado:

// Seleccionamos los elementos
const contenedor = document.getElementById('contenedor');
const boton = document.getElementById('boton');

// Listener en el contenedor durante la fase de BURBUJA (por defecto)
contenedor.addEventListener('click', () => {
  console.log('Contenedor: Fase de burbuja');
});

// Listener en el contenedor durante la fase de CAPTURA
contenedor.addEventListener('click', () => {
  console.log('Contenedor: Fase de captura');
}, { capture: true });

// Listener en el botón
boton.addEventListener('click', () => {
  console.log('Botón clickeado (fase objetivo)');
});Lenguaje del código: JavaScript (javascript)

Explicación:

  1. Cuando el usuario hace clic en el botón, el navegador inicia la propagación del evento.
  2. Primera fase (captura):
    • El evento desciende desde window hasta llegar al boton.
    • El addEventListener del contenedor con { capture: true } se activa aquí →
      🔹 Se muestra en consola: "Contenedor: Fase de captura".
  3. Segunda fase (objetivo):
    • El evento alcanza al boton.
      🔹 Se muestra: "Botón clickeado (fase objetivo)".
  4. Tercera fase (burbujeo):
    • El evento sube nuevamente hasta window, pasando otra vez por el contenedor.
    • El addEventListener sin { capture: true } se activa aquí →
      🔹 Se muestra: "Contenedor: Fase de burbuja".

Resultado en la consola al hacer clic en el botón:

Contenedor: Fase de captura
Botón clickeado (fase objetivo)
Contenedor: Fase de burbuja

3.5. ¿Cómo detener la propagación?

Podés interrumpir el flujo del evento con dos métodos:

  • event.stopPropagation() → detiene que el evento siga propagándose.
  • event.stopImmediatePropagation() → además impide que se ejecuten otros listeners en el mismo elemento.

Ejemplo:

boton.addEventListener('click', (event) => {
  console.log('Botón clickeado');
  event.stopPropagation(); // Detiene la propagación del evento hacia arriba
});Lenguaje del código: JavaScript (javascript)

Ahora, al hacer clic en el botón, solo se ejecuta el listener del botón, y los del contenedor ya no se ejecutan.

4. El objeto event.

4.1. ¿Qué es el objeto event?

Cada vez que ocurre un evento en el DOM (por ejemplo, un clic, una tecla presionada o un envío de formulario), el navegador crea automáticamente un objeto especial: el objeto Event (o una de sus subclases).

Este objeto contiene toda la información sobre el evento:

  • Qué tipo de evento fue (click, keydown, submit, etc.).
  • En qué elemento ocurrió.
  • En qué momento.
  • Y muchos más detalles según el tipo de evento (posición del mouse, tecla presionada, etc.).

Además, incluye métodos que te permiten controlar el flujo del evento (por ejemplo, detener su propagación o evitar una acción por defecto).

4.2. ¿Cómo usar el objeto event para ver esta información?

Para acceder a la información contenida en el Objeto Event (comúnmente llamado e o event), simplemente debes incluirlo como un parámetro en la función manejadora que adjuntas usando addEventListener().

Cuando el evento se dispara, el navegador lo pasa automáticamente a esa función. Una vez dentro de la función, puedes acceder a sus propiedades (para obtener datos) y llamar a sus métodos (para controlar el evento).

Sintaxis:

elemento.addEventListener('tipoDeEvento', (e) => {
  // Aquí, 'e' es el Objeto Event
  
  // 1. Acceder a Propiedades:
  console.log('Tipo de Evento:', e.type);
  console.log('Elemento Origen:', e.target);
  
  // 2. Llamar a Métodos:
  e.preventDefault(); // Por ejemplo, para detener la acción predeterminada.
});Lenguaje del código: JavaScript (javascript)

4.2.1. Ejemplo práctico: Propiedades básicas del objeto Event

HTML

<div id="contenedor">
  <button id="boton">Haz clic aquí</button>
</div>
Lenguaje del código: HTML, XML (xml)

JavaScript

const contenedor = document.getElementById('contenedor');
const boton = document.getElementById('boton');

contenedor.addEventListener('click', (event) => {
  console.log('--- Información del Evento ---');
  console.log('Tipo de evento:', event.type);
  console.log('Elemento originario:', event.target);
  console.log('Elemento manejador actual:', event.currentTarget);
  console.log('¿Burbujea?:', event.bubbles);
  console.log('¿Cancelable?:', event.cancelable);
  console.log('Momento en que ocurrió:', event.timeStamp);
});
Lenguaje del código: JavaScript (javascript)

Explicación:

  1. Cuando el usuario hace clic en el botón, el evento "click" burbujea hasta el div contenedor.
  2. El navegador pasa el objeto Event como argumento al listener.
  3. En la consola podés inspeccionar todas las propiedades:
    • type: "click"
    • target: el botón (donde realmente se hizo clic)
    • currentTarget: el contenedor (donde está el listener)
    • bubbles: true (porque el evento sube)
    • cancelable: true (podríamos detener una acción por defecto)
    • timeStamp: valor numérico que indica el momento del clic

4.2.2. Propiedades más importantes del objeto Event

Veamos las principales y qué información te aportan.

Propiedad Descripción Ejemplo de Valor
type Tipo de evento (por ejemplo «click», «keydown»). "click"
target Elemento donde se originó el evento. <button id="btn">
currentTarget Elemento que actualmente maneja el evento. <div id="contenedor">
bubbles Indica si el evento burbujea hacia los padres. true o false
cancelable Indica si el evento puede ser cancelado con preventDefault(). true o false
timeStamp Momento en milisegundos desde que se cargó el documento. 1234.56

4.3. Métodos importantes del objeto Event

En el punto anterior vimos cómo usar y visualizar la información del objeto event. Pero además de contener datos útiles sobre el evento, este objeto también nos permite ejecutar acciones específicas a través de sus métodos incorporados.

Estos métodos sirven, por ejemplo, para detener la propagación de un evento, cancelar su acción por defecto o controlar el flujo de ejecución de los listeners.

Veamos los más utilizados y potentes, con ejemplos claros

4.3.1. event.stopPropagation()

Evita que el evento siga subiendo (o bajando) por el DOM.

Ejemplo:

boton.addEventListener('click', (event) => {
  event.stopPropagation();
  console.log('Clic en el botón, sin burbujear al contenedor');
});
Lenguaje del código: JavaScript (javascript)

En este caso, el clic solo afecta al botón y no llega al contenedor.

4.3.2. event.stopImmediatePropagation()

Hace lo mismo que stopPropagation(), pero además impide que otros listeners del mismo elemento se ejecuten.

Ejemplo:

boton.addEventListener('click', (event) => {
  console.log('Primer listener');
  event.stopImmediatePropagation();
});

boton.addEventListener('click', () => {
  console.log('Segundo listener');
});
Lenguaje del código: JavaScript (javascript)

Resultado: Solo se ejecuta "Primer listener", el segundo se cancela automáticamente.

4.3.3. event.preventDefault()

Evita que ocurra la acción por defecto del navegador.

Por ejemplo, en formularios o enlaces:

HTML

<a href="https://www.google.com" id="link">Ir a Google</a>
Lenguaje del código: HTML, XML (xml)

JavaScript

const link = document.getElementById('link');

link.addEventListener('click', (event) => {
  event.preventDefault(); // Evita que el navegador abra el enlace
  console.log('Acción por defecto detenida');
});
Lenguaje del código: JavaScript (javascript)

Esto es muy útil para validar formularios, manejar navegación SPA o controlar acciones del usuario.

4.4. Los subtipos del objeto Event

Como ya dijimos, el objeto Event es la clase base que usa el navegador para representar cualquier tipo de evento en el DOM.
Sin embargo, cada tipo de interacción del usuario (clics, teclas, toques, enfoque, etc.) necesita información específica.

Por eso existen subtipos especializados de Event, que heredan todas las propiedades generales del objeto base (type, target, bubbles, etc.) y además añaden propiedades únicas para su contexto.

En otras palabras: «Los subtipos del objeto Event permiten acceder a información más detallada sobre lo que ocurrió, dependiendo del tipo de interacción del usuario o del sistema».

4.4.1. Principales subtipos y para qué sirven

📌MouseEvent

Qué es:
Representa eventos generados por interacciones con el mouse, el touchpad o el clic táctil.

Propiedades adicionales:

  • clientX y clientY: posición del puntero respecto a la ventana del navegador.
  • button: qué botón del mouse se usó (0 = izquierdo, 1 = medio, 2 = derecho).

Ejemplo:

<button id="miBoton">Haz clic aquí</button>

<script>
const boton = document.getElementById('miBoton');

boton.addEventListener('click', (event) => {
  console.log('Tipo:', event.type); // click
  console.log('Coordenadas X:', event.clientX);
  console.log('Coordenadas Y:', event.clientY);
  console.log('Botón del mouse:', event.button);
});
</script>
Lenguaje del código: HTML, XML (xml)

Explicación:
Cuando el usuario hace clic, el navegador genera un MouseEvent que contiene no solo el tipo "click", sino también la posición del puntero y qué botón se usó.
Esto permite, por ejemplo, crear interfaces gráficas que respondan a clics en lugares específicos de la pantalla.

📌KeyboardEvent

Qué es:
Se dispara cuando el usuario presiona o suelta una tecla.

Propiedades adicionales:

  • key: la tecla presionada (por ejemplo, "a", "Enter", "Escape").
  • code: el código físico de la tecla (por ejemplo, "KeyA", "Space").
  • altKey, ctrlKey, shiftKey: indican si esas teclas modificadoras estaban presionadas.

Ejemplo:

<input type="text" id="campoTexto" placeholder="Escribí algo...">

<script>
const input = document.getElementById('campoTexto');

input.addEventListener('keydown', (event) => {
  console.log('Tecla presionada:', event.key);
  console.log('Código de tecla:', event.code);
  console.log('¿Ctrl presionado?:', event.ctrlKey);
});
</script>
Lenguaje del código: HTML, XML (xml)

Explicación:
Cada vez que el usuario presiona una tecla dentro del campo de texto, el navegador genera un KeyboardEvent.
Este evento contiene información detallada sobre la tecla y el contexto, lo cual es esencial para crear atajos de teclado o validaciones personalizadas.

📌 TouchEvent

Qué es:
Representa interacciones táctiles en dispositivos móviles o pantallas táctiles.

Propiedades adicionales:

  • touches: lista de todos los puntos de contacto activos.
  • changedTouches: lista de los toques que cambiaron desde el último evento.
  • targetTouches: toques específicos sobre el mismo elemento.

Ejemplo:

<div id="areaTactil" style="width:200px; height:200px; background:#cce;">
  Toca aquí
</div>

<script>
const area = document.getElementById('areaTactil');

area.addEventListener('touchstart', (event) => {
  console.log('Toques activos:', event.touches.length);
  console.log('Primer toque X:', event.touches[0].clientX);
  console.log('Primer toque Y:', event.touches[0].clientY);
});
</script>
Lenguaje del código: HTML, XML (xml)

Explicación:
Cuando el usuario toca el área, se dispara un TouchEvent con datos sobre todos los puntos de contacto.
Esto es vital para crear gestos (como arrastrar, pellizcar o deslizar) en apps móviles.

📌 FocusEvent

Qué es:
Ocurre cuando un elemento gana o pierde el foco, generalmente en campos de formulario.

Propiedades adicionales:

  • relatedTarget: elemento que perdió o ganó el foco durante la transición.

Ejemplo:

<input type="text" id="nombre" placeholder="Tu nombre">

<script>
const input = document.getElementById('nombre');

input.addEventListener('focus', (event) => {
  console.log('El campo tiene el foco:', event.target);
});

input.addEventListener('blur', (event) => {
  console.log('El campo perdió el foco:', event.target);
});
</script>
Lenguaje del código: HTML, XML (xml)

Explicación:
FocusEvent es útil para mostrar ayudas, validar campos o resaltar visualmente el elemento activo en formularios.

📌 InputEvent

Qué es:
Se dispara cuando cambia el valor de un campo de texto mientras el usuario escribe.

Propiedad adicional:

  • data: carácter ingresado.
  • inputType: tipo de cambio (inserción, borrado, reemplazo, etc.).

Ejemplo:

<input type="text" id="campo" placeholder="Escribí algo...">

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

campo.addEventListener('input', (event) => {
  console.log('Texto actual:', event.target.value);
  console.log('Tipo de entrada:', event.inputType);
});
</script>
Lenguaje del código: HTML, XML (xml)

Explicación:
Permite detectar en tiempo real lo que escribe el usuario, ideal para buscadores en vivo o validaciones instantáneas.

📌 CustomEvent

Qué es:
Permite crear eventos personalizados definidos por el programador, para comunicación entre distintos componentes del código.

Propiedades adicionales:

  • detail: contiene información adicional que se pasa con el evento.

Ejemplo:

<div id="receptor"></div>

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

// Escuchar un evento personalizado
receptor.addEventListener('saludo', (event) => {
  console.log('Evento personalizado recibido:', event.detail.mensaje);
});

// Crear y despachar el evento
const eventoPersonalizado = new CustomEvent('saludo', {
  detail: { mensaje: '¡Hola desde CustomEvent!' }
});

receptor.dispatchEvent(eventoPersonalizado);
</script>
Lenguaje del código: HTML, XML (xml)

Explicación:
Los CustomEvent se usan para comunicar cambios o acciones dentro de una app sin depender de eventos del navegador.
Por ejemplo, entre componentes JavaScript o módulos en una SPA.

4.5. Conclusión:

El objeto Event es solo la base.
Los subtipos (MouseEvent, KeyboardEvent, TouchEvent, FocusEvent, InputEvent, CustomEvent) son lo que realmente te permiten interactuar con precisión según el contexto del usuario.

Dominar estos subtipos te permite construir interfaces interactivas, accesibles y totalmente personalizadas.

5. Delegación de eventos (Event delegation)

La delegación de eventos es un patrón avanzado del DOM que permite manejar eventos de múltiples elementos desde un único listener, colocado en un elemento ancestro común.

En lugar de agregar un addEventListener() a cada elemento hijo, colocás un solo listener en un elemento superior, y usás propiedades como event.target o métodos como closest() para determinar qué hijo disparó el evento.

Es uno de los patrones más importantes para escribir código eficiente, limpio y escalable en JavaScript.

5.1. ¿Qué es exactamente la delegación de eventos?

Consiste en:

  1. Escuchar el evento en un contenedor padre (o un ancestro común).
  2. Permitir que el evento burbujee (suba desde el elemento original hasta el padre).
  3. En el listener del contenedor, usar event.target o event.target.closest() para saber qué elemento hijo originó el evento.
  4. Ejecutar lógica solo si coincide con lo que queremos manejar.

5.2. ¿Para qué sirve?

1️⃣ Para evitar múltiples listeners innecesarios:

En vez de esto:

items.forEach(item => {
  item.addEventListener('click', handler);
});
Lenguaje del código: JavaScript (javascript)

Usás:

list.addEventListener('click', handler);
Lenguaje del código: PHP (php)

2️⃣ Para mejorar el rendimiento:

Menos listeners = menos memoria + menos trabajo del navegador.

3️⃣ Para manejar elementos agregados dinámicamente:

Funciona incluso si los elementos hijos:

  • se crean después,
  • se cargan por AJAX,
  • se insertan con innerHTML(),
  • o se generan en tiempo real.

No tenés que volver a registrar listeners para los nuevos elementos.

5.3. ¿Cómo se hace?

const list = document.querySelector('#lista');

list.addEventListener('click', (e) => {
  const item = e.target.closest('.item'); // ¿Hizo clic en un .item (o dentro)?
  if (!item) return; // Si no, ignora

  console.log('Click en el ítem:', item.dataset.id);
});
Lenguaje del código: PHP (php)

Explicación:

  1. list.addEventListener('click', ...)
    • Registrás un solo listener en el <ul> o en cualquier contenedor que envuelva a los ítems.
  2. El usuario hace clic en algún elemento dentro de la lista
    • Puede ser:
      • el <li>
      • un <span> dentro del <li>
      • un <button> dentro del <li>
  3. El evento “burbujea” hacia arriba
    • Primero se dispara en el elemento exacto clickeado
      • → luego sube por el DOM
      • → llega al contenedor .lista
  4. event.target indica dónde ocurrió el clic
    • Es el elemento más interno donde se originó el evento.
  5. closest('.item')
    • Permite “escalar” hacia arriba y encontrar el <li> que nos interesa.
    • Si el usuario clickeó en un <span> dentro del item, closest() lo ubica igual.
  6. Si no hay coincidencia
    • if (!item) return;
    • Ignoramos el clic porque no ocurrió en un elemento relevante.

5.4. ¿Cuándo usar delegación de eventos?

  • ✔ Cuando hay muchos elementos similares (lista, galería, tabla, menú).
  • ✔ Cuando los elementos se crean o eliminan con frecuencia.
  • ✔ Cuando querés optimizar el rendimiento.
  • ✔ Cuando querés mantener el código limpio y fácil de escalar.

5.5. ¿Cuándo No Usarla?

  • ✖ Si los elementos hijos tienen lógica muy diferente entre sí.
  • ✖ Si el evento NO burbujea (ej: focus, blur).
  • ✖ Si el contenedor tiene demasiados niveles internos y complica identificar el target.

6. Eventos personalizados (Custom events)

Los Custom Events son eventos creados por vos mismo, no por el navegador. Te permiten generar tus propios nombres de evento, enviar datos personalizados y comunicar diferentes partes de tu aplicación de forma ordenada.

6.1. ¿Qué son?

Un Custom Event es un objeto de tipo CustomEvent que extiende al objeto Event.
Esto significa que tiene todo lo que tiene un evento normal, pero con la ventaja de poder agregar datos propios dentro de la propiedad detail.

Es como crear tu propio evento “click”, “submit”, etc., pero con un nombre único y contenido personalizado.

6.2. ¿Para qué sirven?

Los eventos personalizados permiten:

  1. Comunicación entre diferentes componentes
    • Por ejemplo, cuando un componente termina un proceso y necesita avisar al resto.
  2. Notificar cambios de estado
    • Ejemplo: cuando un usuario inicia sesión, carga de datos terminada, carrito actualizado, etc.
  3. Hacer que tus módulos JS sean más desacoplados
    • En vez de que un módulo llame directamente al otro, “dispara un evento” y quien lo necesite lo escucha.
  4. Integración entre librerías, widgets o micro-frontends
    • Cada pieza puede emitir eventos que la otra escucha sin depender entre sí.

6.3. ¿Cómo crear y disparar un evento personalizado?

const event = new CustomEvent('usuario:logueado', {
  detail: { userId: 123, nombre: 'Facundo' }
});

document.dispatchEvent(event);
Lenguaje del código: JavaScript (javascript)

Explicación:

  • ‘usuario:logueado’ → nombre del evento (lo decidís vos).
  • detail → objeto donde enviás datos personalizados.
  • dispatchEvent() → dispara el evento para que los listeners lo reciban.

6.4. ¿Cómo escucharlo?

document.addEventListener('usuario:logueado', (e) => {
  console.log('Usuario logueado con ID:', e.detail.userId);
  console.log('Nombre:', e.detail.nombre);
});
Lenguaje del código: JavaScript (javascript)

Explicación:

  • addEventListener(‘usuario:logueado’) → escuchamos nuestro evento personalizado.
  • e.detail → contiene los datos enviados al dispararlo.

7. Buenas prácticas en el manejo de eventos en el DOM.

7.1. Evitar repintados excesivos (Reflow y Repaint)

La manipulación del DOM es el cuello de botella más grande en el rendimiento del front-end. Cada vez que cambias la estructura, el diseño o la visibilidad de un elemento, el navegador debe recalcular las dimensiones de todos los elementos afectados (Reflow) y luego volver a dibujar (Repaint) la pantalla. Hacer esto repetidamente es muy costoso.

7.1.1. Manipulación en bloque (Document Fragments)

La solución es realizar todas tus modificaciones fuera de la vista del navegador y luego «entregarlas» al DOM en una sola operación.

ConceptoExplicación
Reflow/LayoutRecálculo de la posición y geometría de los elementos. (El más costoso).
RepaintRedibujo de los píxeles en la pantalla. (Menos costoso que Reflow).

La técnica más eficiente para esto es usar document.createDocumentFragment().

Ejemplo de DocumentFragment:

const lista = document.getElementById('miLista');
const fragmento = document.createDocumentFragment();

// Imagina que queremos añadir 100 elementos de lista
for (let i = 1; i <= 100; i++) {
  const nuevoItem = document.createElement('li');
  nuevoItem.textContent = `Elemento ${i}`;
  
  // Añadimos el nuevo elemento al fragmento (NO al DOM real)
  fragmento.appendChild(nuevoItem);
}

// Una sola operación costosa: añadir el fragmento completo
lista.appendChild(fragmento); Lenguaje del código: JavaScript (javascript)

El navegador solo ejecuta 1 Reflow/Repaint, en lugar de 100.

7.2. Throttling y Debouncing

Estas son dos técnicas de optimización esenciales para controlar la frecuencia con la que se ejecutan las funciones que responden a eventos de alta frecuencia, como scroll, mousemove (movimiento del ratón), resize (redimensionar la ventana) o input (teclear).

7.2.1. Debouncing (Retraso)

El Debouncing garantiza que la función se ejecute solo después de que haya pasado un período de inactividad desde la última vez que se disparó el evento.

  • Uso Ideal: Campos de búsqueda con autocompletar. Esperas a que el usuario termine de escribir antes de enviar la solicitud al servidor.

7.2.3. Throttling (Limitación)

El Throttling garantiza que la función se ejecute a lo sumo una vez cada cierto intervalo de tiempo (ej. una vez cada 200ms), sin importar cuántas veces se dispare el evento en ese intervalo.

  • Uso Ideal: Manejadores de eventos scroll o resize. Quieres actualizar la interfaz de usuario periódicamente (por ejemplo, para mostrar una animación) sin sobrecargar el procesador.

Ejemplo de Throttling (Alto Nivel):

// Imagina una función externa 'throttle(funcion, milisegundos)'

window.addEventListener('scroll', throttle(() => {
  console.log('El scroll se ejecutó, pero solo una vez cada 100ms');
  // Lógica para actualizar el encabezado pegajoso
}, 100));Lenguaje del código: JavaScript (javascript)

Si el usuario se desplaza muy rápido (disparando el evento 50 veces en 1 segundo), la función manejadora real solo se ejecutará 10 veces (1000ms / 100ms).

7.3. Manejo de Errores con try...catch

Como profesional, debes asumir que el código puede fallar, especialmente cuando interactúa con el DOM, que puede ser modificado por otros scripts o el usuario.

El bloque try...catch te permite «intentar» ejecutar un código y, si falla, «capturar» el error para que tu aplicación no se bloquee ni muestre una página en blanco.

Ejemplo de manejo de errores en DOM:

function actualizarUsuario(datos) {
  try {
    // 1. Bloque TRY: Código que podría fallar
    const nombreElemento = document.getElementById('user-name-display');
    
    if (!nombreElemento) {
      // Lanzamos un error si el elemento no existe (mejor que dejar que falle el código)
      throw new Error("Elemento 'user-name-display' no encontrado en el DOM.");
    }
    
    // Si el elemento existe, actualizamos
    nombreElemento.textContent = datos.nombre; 

  } catch (error) {
    // 2. Bloque CATCH: Si algo falla en el TRY, el control va aquí
    console.error("ERROR CRÍTICO al actualizar la UI:", error.message);
    
    // Aquí puedes mostrar un mensaje de error amigable al usuario
    // o enviar el error a un servicio de logging.
  }
}Lenguaje del código: JavaScript (javascript)

Si por alguna razón la ID del elemento en el HTML está mal o no existe, el programa entrará al ‘catch’ en lugar de detener la ejecución del script por completo.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *