Contenido
1. Qué es un evento
Un evento es cualquier interacción que ocurre en la página:
- El usuario hace clic
- Escribe en un input
- Envía un formulario
- Mueve el ratón
- Pulsa una tecla
- La página termina de cargar
Cuando ocurre algo → el navegador lo detecta → JavaScript puede reaccionar.
El DOM no es solo un árbol… es un sistema reactivo.
2. Qué es un Event Listener
Un Event Listener es una función que espera a que ocurra un evento.
Cuando el evento ocurre → se ejecuta la función.
La forma moderna y correcta de escuchar eventos es:
elemento.addEventListener("evento", funcion);
3. Sintaxis de addEventListener
boton.addEventListener("click", () => {
console.log("Se hizo clic");
});
Parámetros:
- Tipo de evento →
"click" - Función a ejecutar → callback
4. Ejemplo básico
HTML:
<buttonid="btn">Haz clic</button>
JavaScript:
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
alert("Botón pulsado");
});
5. El objeto event
Cada vez que ocurre un evento, JavaScript genera un objeto llamado event que contiene información.
btn.addEventListener("click", (event) => {
console.log(event);
});
Propiedades útiles:
| Propiedad | Qué indica |
|---|---|
event.target | Elemento que disparó el evento |
event.type | Tipo de evento |
event.clientX | Posición X del ratón |
event.clientY | Posición Y del ratón |
event.key | Tecla pulsada |
event.preventDefault() | Evita comportamiento por defecto |
event.stopPropagation() | Detiene propagación |
6. Eventos más comunes
Click
element.addEventListener("click", fn);
Input (cuando el usuario escribe)
input.addEventListener("input", fn);
Change (cuando cambia valor)
select.addEventListener("change", fn);
Submit (formularios)
form.addEventListener("submit", fn);
Keydown (teclado)
document.addEventListener("keydown", fn);
Mouseover
element.addEventListener("mouseover", fn);
7. Evitar comportamiento por defecto
Ejemplo: evitar que un formulario recargue la página.
form.addEventListener("submit", (e) => {
e.preventDefault();
console.log("Formulario capturado");
});
8. Propagación de eventos (Bubbling)
Cuando ocurre un evento, no solo afecta al elemento… sube por el árbol DOM.
Ejemplo:
<div id="padre">
<button id="hijo">Click</button>
</div>
padre.addEventListener("click", () => console.log("Padre"));
hijo.addEventListener("click", () => console.log("Hijo"));
Resultado al hacer click:
Hijo
Padre
Primero el elemento → luego sus padres.
9. Detener propagación
hijo.addEventListener("click", (e) => {
e.stopPropagation();
});
10. Delegación de eventos (muy importante)
En lugar de añadir eventos a cada elemento, se añade uno solo al contenedor.
tabla.addEventListener("click", (e) => {
if (e.target.classList.contains("btn-ver")) {
const id = e.target.dataset.id;
console.log("Ver registro", id);
}
});
Ventajas:
- Funciona con elementos creados dinámicamente
- Mejor rendimiento
- Menos código
Esto es fundamental cuando el DOM se genera con JavaScript.
11. Eliminar eventos
function clickHandler() {
console.log("Click");
}
btn.addEventListener("click", clickHandler);
btn.removeEventListener("click", clickHandler);
La función debe ser la misma referencia.
12. Eventos en elementos creados dinámicamente
Cuando creas un elemento con JavaScript, debes añadir el listener manualmente.
const boton = document.createElement("button");
boton.textContent = "Eliminar";
boton.addEventListener("click", () => {
console.log("Elemento eliminado");
});
Tabla de eventos en JavaScript
🖱️ Eventos del ratón
| Evento | Cuándo ocurre | Uso típico |
|---|---|---|
click | Clic normal | Botones, enlaces |
dblclick | Doble clic | Acciones especiales |
mousedown | Pulsar botón ratón | Drag, control |
mouseup | Soltar botón | Finalizar acción |
mousemove | Mover ratón | Tracking, dibujo |
mouseover | Entrar en elemento | Hover |
mouseout | Salir de elemento | Quitar hover |
mouseenter | Entrar (sin bubbling) | UI precisa |
mouseleave | Salir (sin bubbling) | UI precisa |
contextmenu | Clic derecho | Menú contextual |
⌨️ Eventos del teclado
| Evento | Cuándo ocurre | Uso típico |
|---|---|---|
keydown | Tecla presionada | Detectar tecla |
keyup | Tecla liberada | Confirmar entrada |
keypress | Tecla mantenida (deprecated) | Evitar usar |
Propiedad útil: event.key
📝 Eventos de formularios / inputs
| Evento | Cuándo ocurre | Uso típico |
|---|---|---|
input | Cambia el valor en tiempo real | Validación viva |
change | Valor confirmado | Select, checkbox |
submit | Envío de formulario | Capturar datos |
reset | Reset formulario | Restaurar |
focus | Elemento recibe foco | UX |
blur | Elemento pierde foco | Validación |
invalid | Validación HTML falla | Formularios |
📄 Eventos del documento / ventana
| Evento | Cuándo ocurre | Uso típico |
|---|---|---|
DOMContentLoaded | DOM listo | Inicializar app |
load | Página completamente cargada | Recursos |
resize | Cambia tamaño ventana | Responsive |
scroll | Scroll de página | Lazy load |
beforeunload | Antes de salir | Confirmación |
unload | Página se cierra | Limpieza |
🎯 Eventos de interacción avanzada
| Evento | Cuándo ocurre | Uso típico |
|---|---|---|
dragstart | Inicio drag | Drag & Drop |
dragover | Arrastrando encima | Drop zones |
drop | Soltar elemento | Upload |
touchstart | Tocar pantalla | Móvil |
touchmove | Deslizar | Gestos |
touchend | Fin toque | Mobile UI |
pointerdown | Input universal | Multiplataforma |
📡 Eventos de red y estado
| Evento | Cuándo ocurre | Uso típico |
|---|---|---|
online | Vuelve conexión | Reintentar |
offline | Sin conexión | Avisar |
error | Error recurso | Debug |
abort | Cancelación | Fetch |
🎬 Eventos multimedia
| Evento | Cuándo ocurre | Uso típico |
|---|---|---|
play | Reproducir | Video/audio |
pause | Pausar | Control |
ended | Finaliza media | Loop |
timeupdate | Tiempo cambia | Barra progreso |
volumechange | Volumen cambia | UI |
🧠 Propiedades comunes del objeto event
| Propiedad | Qué indica |
|---|---|
event.target | Elemento que disparó el evento |
event.currentTarget | Elemento con listener |
event.type | Tipo de evento |
event.key | Tecla |
event.clientX/Y | Posición ratón |
event.preventDefault() | Evita comportamiento |
event.stopPropagation() | Detiene bubbling |
Ejemplo guiado: cargar JSON por fetch al inicio y pintarlo en el DOM
- Al abrir la página, se ejecuta código al evento
DOMContentLoaded - Se llama a un endpoint con
fetch() - Se convierte la respuesta a JSON
- Se renderiza una tabla en el DOM
- Se manejan estados: cargando / error / sin datos
1) HTML (estructura base)
Crea un archivo index.html:
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>JSON → DOM</title>
<style>
body { font-family: system-ui, Arial; padding: 20px; }
.status { padding: 10px; border-radius: 8px; margin: 10px 0; }
.loading { background: #fff3cd; }
.error { background: #f8d7da; }
.ok { background: #d1e7dd; }
table { border-collapse: collapse; width: 100%; margin-top: 10px; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background: #f3f3f3; }
</style>
</head>
<body>
<h1>Listado de coches</h1>
<div id="status" class="status loading">Cargando...</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>Marca</th>
<th>Modelo</th>
<th>Precio</th>
</tr>
</thead>
<tbody id="rows"></tbody>
</table>
<script src="app.js"></script>
</body>
</html>
Qué estamos preparando aquí
- Un
div#statuspara mostrar mensajes (cargando/error/vacío). - Un
tbody#rowsdonde vamos a insertar filas dinámicamente. - Cargamos
app.jsal final.
2) JavaScript (cargar y pintar)
Crea un archivo app.js:
// 1) Este evento se dispara cuando el DOM ya está construido.
// (Importante: aún puede que imágenes o recursos no hayan cargado, pero el HTML sí.)
document.addEventListener("DOMContentLoaded", () => {
loadCars();
});
// 2) Función principal: obtiene datos y renderiza
async function loadCars() {
try {
setStatus("Cargando...", "loading");
// Cambia esta URL por tu endpoint real (por ejemplo en JEE: /miApp/api/coches)
const url = "coches.json"; // Para pruebas: archivo local con JSON
const response = await fetch(url);
// 3) Comprobamos si la respuesta HTTP es correcta
if (!response.ok) {
throw new Error(`HTTP ${response.status} - ${response.statusText}`);
}
// 4) Convertimos el body a JSON (array de objetos)
const cars = await response.json();
// 5) Si no hay datos, mostramos estado vacío
if (!Array.isArray(cars) || cars.length === 0) {
clearRows();
setStatus("No hay datos disponibles.", "ok");
return;
}
// 6) Pintamos los datos
renderCars(cars);
setStatus(`Cargados ${cars.length} registros.`, "ok");
} catch (error) {
clearRows();
setStatus(`Error cargando datos: ${error.message}`, "error");
}
}
// --- Renderizado ---
function renderCars(cars) {
const tbody = document.getElementById("rows");
tbody.innerHTML = ""; // limpiamos antes de pintar
// Creamos un fragmento para insertar todo de golpe (más eficiente)
const fragment = document.createDocumentFragment();
cars.forEach(car => {
fragment.append(createRow(car));
});
tbody.append(fragment);
}
function createRow(car) {
const tr = document.createElement("tr");
const tdId = document.createElement("td");
tdId.textContent = car.id;
const tdMarca = document.createElement("td");
tdMarca.textContent = car.marca;
const tdModelo = document.createElement("td");
tdModelo.textContent = car.modelo;
const tdPrecio = document.createElement("td");
tdPrecio.textContent = car.precio;
tr.append(tdId, tdMarca, tdModelo, tdPrecio);
return tr;
}
function clearRows() {
document.getElementById("rows").innerHTML = "";
}
// --- Estado UI (mensajes) ---
function setStatus(message, type) {
const status = document.getElementById("status");
status.textContent = message;
// Reseteamos clases y aplicamos la nueva
status.classList.remove("loading", "error", "ok");
status.classList.add(type);
}
Qué has aprendido aquí
DOMContentLoadedasegura que el HTML existe antes de seleccionar nodos.fetch()hace la petición.response.okcomprueba si el HTTP fue bien.response.json()parsea la respuesta.renderCars()separa “pintar” de “cargar datos”.setStatus()maneja estados.
3) JSON de prueba (para que funcione sin backend)
Crea coches.json en la misma carpeta:
[
{ "id": 1, "marca": "Toyota", "modelo": "Corolla", "precio": 20000 },
{ "id": 2, "marca": "Ford", "modelo": "Focus", "precio": 18000 },
{ "id": 3, "marca": "Seat", "modelo": "Ibiza", "precio": 15500 }
]
4) Nota importante (muy típica en clase)
Si abres index.html haciendo doble clic (ruta file://), en algunos navegadores el fetch("coches.json") puede fallar por permisos.
Soluciones sencillas para clase:
- Servirlo desde un servidor local (ideal).
- Si ya estás con JEE, sirve la página desde tu propio proyecto y el endpoint desde el servlet.
5) Conectarlo a JEE
Cuando tengas tu endpoint en JEE, normalmente será algo así:
- URL:
/miApp/api/coches - Devuelve JSON
Solo cambias:
consturl="/miApp/api/coches";
Y listo.





![[Reto] - Tu propio juego con Slider y DOM d387b361-1c06-49dc-9112-e118ab38c3ba](https://laaventuradeaprender.com/wp-content/uploads/2026/02/d387b361-1c06-49dc-9112-e118ab38c3ba-150x150.png)

