Volver al inicio
Eventos en JavaScript

Eventos en JavaScript

Los eventos permiten que tu página web responda a las acciones del usuario: clics, teclas, envío de formularios y mucho más.

1. ¿Qué son los eventos?

Un evento es una acción que ocurre en tu página web: hacer clic en un botón, escribir en un input, mover el ratón, etc. JavaScript puede "escuchar" estos eventos y ejecutar código cuando ocurren.

Comparación con Java: Es similar a los ActionListener o EventHandler en Java Swing/JavaFX, pero mucho más sencillo de usar.

addEventListener - Escuchar eventosjavascript
1// Sintaxis básica
2elemento.addEventListener('evento', función);
3
4// Ejemplo: Click en un botón
5const boton = document.querySelector('#miBoton');
6
7boton.addEventListener('click', function() {
8 console.log('¡Botón clickeado!');
9});
10
11// Con arrow function (más común)
12boton.addEventListener('click', () => {
13 console.log('¡Botón clickeado!');
14});

2. Evento: click

El evento click se dispara cuando el usuario hace clic en un elemento.

Ejemplo: Contador con clickhtml
1<!DOCTYPE html>
2<html>
3<head>
4 <style>
5 .contador {
6 font-size: 48px;
7 text-align: center;
8 margin: 20px 0;
9 }
10 button {
11 padding: 10px 20px;
12 font-size: 16px;
13 cursor: pointer;
14 margin: 5px;
15 }
16 </style>
17</head>
18<body>
19 <div class="contador">0</div>
20 <button id="incrementar">Incrementar</button>
21 <button id="decrementar">Decrementar</button>
22 <button id="resetear">Resetear</button>
23
24 <script>
25 let contador = 0;
26 const display = document.querySelector('.contador');
27
28 document.querySelector('#incrementar').addEventListener('click', () => {
29 contador++;
30 display.textContent = contador;
31 });
32
33 document.querySelector('#decrementar').addEventListener('click', () => {
34 contador--;
35 display.textContent = contador;
36 });
37
38 document.querySelector('#resetear').addEventListener('click', () => {
39 contador = 0;
40 display.textContent = contador;
41 });
42 </script>
43</body>
44</html>

3. El objeto event

Cuando ocurre un evento, JavaScript crea un objeto event con información sobre lo que pasó. Puedes recibirlo como parámetro en tu función. Los eventos se pueden aplicar a cualquier elemento, incluso al body o window.

Evento en body/window - Ejemplo visualhtml
1<!DOCTYPE html>
2<html>
3<head>
4 <style>
5 body {
6 height: 100vh;
7 margin: 0;
8 display: flex;
9 justify-content: center;
10 align-items: center;
11 background-color: #f3f4f6;
12 cursor: crosshair;
13 }
14 #info {
15 font-size: 24px;
16 text-align: center;
17 padding: 20px;
18 background-color: white;
19 border-radius: 10px;
20 box-shadow: 0 4px 6px rgba(0,0,0,0.1);
21 }
22 #coordenadas {
23 color: #3b82f6;
24 font-weight: bold;
25 font-size: 32px;
26 }
27 </style>
28</head>
29<body>
30 <div id="info">
31 <p>Haz clic en cualquier parte de la página</p>
32 <div id="coordenadas">X: 0, Y: 0</div>
33 <p id="elemento"></p>
34 </div>
35
36 <script>
37 // ⭐ Aplicar evento al BODY (elemento abstracto)
38 document.body.addEventListener('click', (event) => {
39 // event contiene TODA la información del evento
40 const x = event.clientX;
41 const y = event.clientY;
42 const tipo = event.type;
43 const elemento = event.target.tagName;
44
45 // Mostrar información visual
46 document.querySelector('#coordenadas').textContent =
47 `X: ${x}, Y: ${y}`;
48
49 document.querySelector('#elemento').textContent =
50 `Elemento: <${elemento}>`;
51
52 console.log('Tipo de evento:', tipo);
53 console.log('Elemento clickeado:', elemento);
54 console.log('Posición X:', x);
55 console.log('Posición Y:', y);
56 });
57
58 // También funciona con window
59 window.addEventListener('resize', (e) => {
60 console.log('Ventana redimensionada:', window.innerWidth, 'x', window.innerHeight);
61 });
62 </script>
63</body>
64</html>

Eventos en elementos abstractos

Puedes aplicar eventos a elementos "abstractos" como:

  • document.body - Todo el contenido de la página
  • window - La ventana del navegador (resize, scroll)
  • document - El documento completo

4. Evento: input

El evento input se dispara cada vez que el usuario escribe en un campo de texto.

Ejemplo: Actualizar en tiempo realhtml
1<!DOCTYPE html>
2<html>
3<body>
4 <label>Escribe tu nombre:</label>
5 <input type="text" id="nombre" placeholder="Tu nombre...">
6 <p id="saludo"></p>
7
8 <script>
9 const input = document.querySelector('#nombre');
10 const saludo = document.querySelector('#saludo');
11
12 input.addEventListener('input', (e) => {
13 const valor = e.target.value;
14 saludo.textContent = valor ? `¡Hola, ${valor}!` : '';
15 });
16 </script>
17</body>
18</html>

Otros eventos de input útiles

Eventos de teclado e inputjavascript
1const input = document.querySelector('#campo');
2
3// change - Se dispara cuando el input pierde foco y el valor cambió
4input.addEventListener('change', (e) => {
5 console.log('Valor final:', e.target.value);
6});
7
8// focus - Cuando el input recibe foco
9input.addEventListener('focus', () => {
10 console.log('Input enfocado');
11});
12
13// blur - Cuando el input pierde foco
14input.addEventListener('blur', () => {
15 console.log('Input desenfocado');
16});
17
18// keypress - Cuando se presiona una tecla (obsoleto, usa keydown)
19input.addEventListener('keydown', (e) => {
20 console.log('Tecla presionada:', e.key);
21
22 // Ejemplo: Detectar Enter
23 if (e.key === 'Enter') {
24 console.log('¡Enter presionado!');
25 }
26});

5. Evento: submit (formularios)

El evento submit se dispara cuando se envía un formulario. Es MUY IMPORTANTE usar preventDefault() para evitar que la página se recargue.

Ejemplo: Manejar formulariohtml
1<!DOCTYPE html>
2<html>
3<body>
4 <form id="miFormulario">
5 <label>Email:</label>
6 <input type="email" id="email" required>
7
8 <label>Password:</label>
9 <input type="password" id="password" required>
10
11 <button type="submit">Iniciar sesión</button>
12 </form>
13
14 <div id="resultado"></div>
15
16 <script>
17 const form = document.querySelector('#miFormulario');
18 const resultado = document.querySelector('#resultado');
19
20 form.addEventListener('submit', (e) => {
21 // ⚠️ IMPORTANTE: Prevenir recarga de página
22 e.preventDefault();
23
24 // Obtener valores
25 const email = document.querySelector('#email').value;
26 const password = document.querySelector('#password').value;
27
28 // Procesar el formulario
29 console.log('Email:', email);
30 console.log('Password:', password);
31
32 resultado.textContent = `Formulario enviado: ${email}`;
33 });
34 </script>
35</body>
36</html>

⚠️ No olvides preventDefault()

Por defecto, los formularios recargan la página al enviarse. Usa e.preventDefault() para evitarlo y manejar el envío con JavaScript.

6. Delegación de eventos

En lugar de añadir un evento a cada elemento, puedes añadirlo a un contenedor padre y usar event.target para saber qué elemento fue clickeado. Esto es más eficiente cuando tienes muchos elementos.

Delegación de eventoshtml
1<!DOCTYPE html>
2<html>
3<body>
4 <ul id="lista">
5 <li>Item 1</li>
6 <li>Item 2</li>
7 <li>Item 3</li>
8 <li>Item 4</li>
9 <li>Item 5</li>
10 </ul>
11
12 <script>
13 // ❌ Forma ineficiente: Añadir evento a cada <li>
14 // const items = document.querySelectorAll('li');
15 // items.forEach(item => {
16 // item.addEventListener('click', () => {
17 // console.log('Clickeado:', item.textContent);
18 // });
19 // });
20
21 // ✅ Forma eficiente: Delegación de eventos
22 const lista = document.querySelector('#lista');
23
24 lista.addEventListener('click', (e) => {
25 // Verificar que se clickeó un <li>
26 if (e.target.tagName === 'LI') {
27 console.log('Clickeado:', e.target.textContent);
28 e.target.style.backgroundColor = '#3b82f6';
29 e.target.style.color = 'white';
30 }
31 });
32
33 // Ventaja: Funciona incluso con elementos añadidos dinámicamente
34 const nuevoItem = document.createElement('li');
35 nuevoItem.textContent = 'Item 6 (añadido dinámicamente)';
36 lista.append(nuevoItem);
37 // ¡El evento también funciona para este nuevo elemento!
38 </script>
39</body>
40</html>

Ventajas de la delegación

  • Más eficiente (un solo event listener)
  • Funciona con elementos creados dinámicamente
  • Usa menos memoria

7. Eliminacion-Remover eventos (elemento.removeEventListener)

removeEventListenerjavascript
1const boton = document.querySelector('#boton');
2
3// Para remover un evento, necesitas una función con nombre
4function manejarClick() {
5 console.log('Click!');
6}
7
8// Añadir evento
9boton.addEventListener('click', manejarClick);
10
11// Remover evento
12boton.removeEventListener('click', manejarClick);
13
14// ❌ Esto NO funciona (funciones anónimas diferentes)
15boton.addEventListener('click', () => console.log('A'));
16boton.removeEventListener('click', () => console.log('A')); // No se remueve
17
18// ✅ Esto SÍ funciona (misma referencia)
19const handler = () => console.log('B');
20boton.addEventListener('click', handler);
21boton.removeEventListener('click', handler); // Se remueve correctamente

8. Ejercicios Prácticos

Ejercicio 1: Validación de formulario

Crea un formulario de registro con los siguientes campos:

  • Nombre (mínimo 3 caracteres)
  • Email (debe contener @)
  • Contraseña (mínimo 6 caracteres)
  • Al enviar, valida los campos y muestra errores si hay problemas
Ver solución
Solución Ejercicio 1html
1<!DOCTYPE html>
2<html>
3<head>
4 <style>
5 .error {
6 color: #ef4444;
7 font-size: 14px;
8 margin-top: 5px;
9 }
10 input.invalido {
11 border: 2px solid #ef4444;
12 }
13 .exito {
14 color: #10b981;
15 font-weight: bold;
16 }
17 </style>
18</head>
19<body>
20 <form id="registro">
21 <div>
22 <label>Nombre:</label>
23 <input type="text" id="nombre">
24 <div class="error" id="errorNombre"></div>
25 </div>
26
27 <div>
28 <label>Email:</label>
29 <input type="email" id="email">
30 <div class="error" id="errorEmail"></div>
31 </div>
32
33 <div>
34 <label>Contraseña:</label>
35 <input type="password" id="password">
36 <div class="error" id="errorPassword"></div>
37 </div>
38
39 <button type="submit">Registrarse</button>
40 </form>
41
42 <div id="resultado"></div>
43
44 <script>
45 const form = document.querySelector('#registro');
46 const nombre = document.querySelector('#nombre');
47 const email = document.querySelector('#email');
48 const password = document.querySelector('#password');
49
50 form.addEventListener('submit', (e) => {
51 e.preventDefault();
52
53 // Limpiar errores previos
54 document.querySelectorAll('.error').forEach(el => el.textContent = '');
55 document.querySelectorAll('input').forEach(el => el.classList.remove('invalido'));
56
57 let valido = true;
58
59 // Validar nombre
60 if (nombre.value.trim().length < 3) {
61 document.querySelector('#errorNombre').textContent = 'Mínimo 3 caracteres';
62 nombre.classList.add('invalido');
63 valido = false;
64 }
65
66 // Validar email
67 if (!email.value.includes('@')) {
68 document.querySelector('#errorEmail').textContent = 'Email inválido';
69 email.classList.add('invalido');
70 valido = false;
71 }
72
73 // Validar contraseña
74 if (password.value.length < 6) {
75 document.querySelector('#errorPassword').textContent = 'Mínimo 6 caracteres';
76 password.classList.add('invalido');
77 valido = false;
78 }
79
80 // Mostrar resultado
81 if (valido) {
82 document.querySelector('#resultado').innerHTML =
83 '<p class="exito">¡Registro exitoso!</p>';
84 form.reset();
85 }
86 });
87 </script>
88</body>
89</html>

Ejercicio 2: Lista de tareas con eliminar

Crea una lista de tareas donde:

  • Puedas añadir tareas
  • Cada tarea tenga un botón "Eliminar"
  • Al hacer clic en "Eliminar", se borre esa tarea
  • Usa delegación de eventos
Ver solución
Solución Ejercicio 2html
1<!DOCTYPE html>
2<html>
3<head>
4 <style>
5 .tarea {
6 display: flex;
7 justify-content: space-between;
8 align-items: center;
9 padding: 10px;
10 margin: 5px 0;
11 background-color: #f3f4f6;
12 border-radius: 5px;
13 }
14 .btn-eliminar {
15 background-color: #ef4444;
16 color: white;
17 border: none;
18 padding: 5px 10px;
19 border-radius: 3px;
20 cursor: pointer;
21 }
22 </style>
23</head>
24<body>
25 <input type="text" id="inputTarea" placeholder="Nueva tarea...">
26 <button id="btnAgregar">Añadir</button>
27
28 <ul id="listaTareas"></ul>
29
30 <script>
31 const input = document.querySelector('#inputTarea');
32 const btnAgregar = document.querySelector('#btnAgregar');
33 const lista = document.querySelector('#listaTareas');
34
35 // Añadir tarea
36 btnAgregar.addEventListener('click', agregarTarea);
37 input.addEventListener('keypress', (e) => {
38 if (e.key === 'Enter') agregarTarea();
39 });
40
41 function agregarTarea() {
42 const texto = input.value.trim();
43 if (texto === '') return;
44
45 const li = document.createElement('li');
46 li.classList.add('tarea');
47 li.innerHTML = `
48 <span>${texto}</span>
49 <button class="btn-eliminar">Eliminar</button>
50 `;
51
52 lista.append(li);
53 input.value = '';
54 input.focus();
55 }
56
57 // Delegación de eventos para eliminar
58 lista.addEventListener('click', (e) => {
59 if (e.target.classList.contains('btn-eliminar')) {
60 e.target.parentElement.remove();
61 }
62 });
63 </script>
64</body>
65</html>

Ejercicio 3: Cambiar tema (claro/oscuro)

Crea un botón que alterne entre tema claro y oscuro:

  • Crea estilos para tema claro y oscuro
  • Al hacer clic en el botón, cambia entre temas
  • El botón debe mostrar "Tema Oscuro" o "Tema Claro" según corresponda
Ver solución
Solución Ejercicio 3html
1<!DOCTYPE html>
2<html>
3<head>
4 <style>
5 body {
6 transition: background-color 0.3s, color 0.3s;
7 padding: 20px;
8 font-family: Arial, sans-serif;
9 }
10
11 body.claro {
12 background-color: #ffffff;
13 color: #000000;
14 }
15
16 body.oscuro {
17 background-color: #1f2937;
18 color: #ffffff;
19 }
20
21 button {
22 padding: 10px 20px;
23 font-size: 16px;
24 cursor: pointer;
25 border-radius: 5px;
26 border: 2px solid;
27 }
28
29 .claro button {
30 background-color: #1f2937;
31 color: #ffffff;
32 border-color: #1f2937;
33 }
34
35 .oscuro button {
36 background-color: #ffffff;
37 color: #1f2937;
38 border-color: #ffffff;
39 }
40 </style>
41</head>
42<body class="claro">
43 <h1>Cambiar tema</h1>
44 <p>Este es un texto de ejemplo.</p>
45 <button id="btnTema">🌙 Tema Oscuro</button>
46
47 <script>
48 const boton = document.querySelector('#btnTema');
49 const body = document.body;
50
51 boton.addEventListener('click', () => {
52 // Alternar clase
53 if (body.classList.contains('claro')) {
54 body.classList.remove('claro');
55 body.classList.add('oscuro');
56 boton.textContent = '☀️ Tema Claro';
57 } else {
58 body.classList.remove('oscuro');
59 body.classList.add('claro');
60 boton.textContent = '🌙 Tema Oscuro';
61 }
62 });
63 </script>
64</body>
65</html>