Maquetación Web Dinámica / JavaScript para maquetadores: darle vida al DOM
Eventos y listeners: reaccionar a todo
Una interfaz viva REACCIONA: al clic, a lo que escribes, al envío de un
formulario, a una tecla. Cada una de esas cosas es un EVENTO, y tú
"escuchas" los que te importan para responder. Ya usaste addEventListener
para el clic; hoy lo dominas de verdad, junto al objeto event que trae
los detalles de qué acaba de pasar.
El sensor y el aviso
Escuchar eventos
El primer argumento es el NOMBRE del evento ("click", "input",
"submit", "keydown"...), el segundo es la función que corre cuando
ocurre. Esa función recibe el objeto event con todo el contexto.
El objeto event: la nota con los detalles
campo.addEventListener("input", (event) => {
// event.target = el elemento que disparó el evento
const texto = event.target.value; // lo que hay escrito
const largo = texto.length;
});
document.addEventListener("keydown", (event) => {
console.log(event.key); // "Enter", "Escape", "a", " " (espacio)...
});Los tres que más usarás: event.target (el elemento concreto que
disparó el evento — clave en la próxima lección), event.target.value
(el contenido de un input), y event.key (la tecla, por nombre). Hay
muchos más (event.clientX/Y para la posición del mouse, que ya usaste en
canvas), pero con estos cubres casi todo.
preventDefault: cancelar lo que el navegador haría solo
Algunos elementos tienen comportamiento POR DEFECTO: un <form> al
enviarse RECARGA la página; un enlace navega. preventDefault() cancela
ese default para que TÚ manejes la acción con JS:
<form id="form" class="caja">
<label for="msg">Tu mensaje</label>
<input id="msg" type="text" placeholder="Escribe algo..." autocomplete="off">
<p id="contador" class="contador">0 caracteres</p>
<button type="submit">Enviar</button>
<p id="salida" class="salida"></p>
</form>body { font-family: system-ui; padding: 20px; background: #f8fafc; }
.caja { background: white; border: 1px solid #e2e8f0; border-radius: 12px; padding: 20px; max-width: 340px; display: grid; gap: 8px; }
label { font-size: 13px; font-weight: 600; color: #334155; }
input { padding: 9px 12px; border: 1px solid #cbd5e1; border-radius: 8px; font-size: 15px; }
.contador { margin: 0; font-size: 12px; color: #64748b; }
button { padding: 10px; border: 0; border-radius: 8px; background: #6d28d9; color: white; font-weight: 600; font-size: 14px; cursor: pointer; }
.salida { margin: 4px 0 0; font-size: 14px; color: #15803d; font-weight: 600; min-height: 20px; }const form = document.querySelector("#form");
const campo = document.querySelector("#msg");
const contador = document.querySelector("#contador");
const salida = document.querySelector("#salida");
// INPUT: contador en vivo, letra a letra
campo.addEventListener("input", (event) => {
contador.textContent = event.target.value.length + " caracteres";
});
// SUBMIT: preventDefault evita que la página se recargue
form.addEventListener("submit", (event) => {
event.preventDefault(); // sin esto, la página recargaría
const texto = campo.value.trim();
if (texto) {
salida.textContent = "Enviado: " + texto;
campo.value = "";
contador.textContent = "0 caracteres";
}
});Escribe (mira el contador subir en vivo con input) y envía (el mensaje
aparece sin recargar, gracias a preventDefault). Sin ese
preventDefault, el formulario recargaría la página y perderías todo — es
la línea que te da control sobre el envío para validarlo o mandarlo con
JS.
Tu formulario de búsqueda 'parpadea' y se resetea cada vez que lo envías: la página se recarga entera. ¿Qué falta en el listener de submit?
Mini-reto
Hazle a "El Observador" un buscador en vivo: un input que, con el evento
input, filtre las tarjetas de noticia mostrando solo las que contienen
el texto escrito (combina event.target.value con classList para
ocultar/mostrar). Y captura keydown de Escape para limpiar el buscador.
Dos eventos, cero recargas — la sensación de una app moderna.
Qué sigue
Pusiste un listener en un botón. ¿Pero qué haces cuando tienes CIEN botones —o una lista que crece— y no quieres cien listeners? La próxima lección enseña la delegación de eventos: un solo listener inteligente que atiende a todos sus hijos, presentes y futuros. El truco que hace tu código escalable.