Eventos: reaccionar a lo que hace el estudiante
Hasta ahora, todo el código JavaScript que escribiste se ejecutaba una sola vez, apenas la página terminaba de cargar. Pero una actividad que se corrige sola necesita reaccionar: recién actúa cuando el estudiante hace clic en un botón, escribe algo o envía un formulario. Para eso existen los eventos.
🖱️ addEventListener y el evento click
elemento.addEventListener("click", función) conecta un elemento con una función que se ejecuta cada vez que alguien hace clic en él. La función que escribes ahí no corre de inmediato: queda "enganchada", esperando el clic.
Esto es distinto a todo lo que escribiste hasta ahora en Python, donde el programa corre de arriba hacia abajo y termina. Acá el código sigue "vivo", esperando que ocurra algo.
input() para esperar que el usuario escriba algo. La diferencia es que en el navegador no hay una sola espera: puedes enganchar tantos eventos como elementos tengas, y cada uno dispara su propia función de forma independiente.const boton = document.querySelector('#btn-saludo');
boton.addEventListener('click', function () {
console.log('¡Hiciste clic!');
});
🧩 ¿Lo entendiste? · Practica
⌨️ Los eventos input y submit
El evento "input" se dispara cada vez que el valor de un campo de texto cambia — es decir, con cada tecla que el estudiante escribe. Sirve para dar feedback en vivo, sin esperar a que termine de escribir.
El evento "submit" se dispara cuando se envía un formulario (por ejemplo, al hacer clic en un botón de tipo submit). Por defecto, el navegador recarga la página al enviar un formulario — algo que casi nunca queremos en una actividad. Por eso, dentro de la función del evento, se llama a event.preventDefault() para frenar ese comportamiento.
event.preventDefault() en un "submit", la página se recarga entera y pierdes el puntaje y todo el estado que tenías guardado en variables de JavaScript.🧩 ¿Lo entendiste? · Repaso rápido
🧩 Ahora practica
Tomar decisiones: condicionales y comparación
Una vez que un evento se dispara, hay que decidir qué hacer: ¿la respuesta es correcta o no? Para eso usamos condicionales — y hay que tener mucho cuidado con cómo comparamos.
🔀 if / else, === y los operadores lógicos
if (condición) { ... } else { ... } funciona igual que en Python, solo que la condición va entre paréntesis y los bloques entre llaves en vez de indentación.
Para comparar igualdad, JavaScript tiene dos operadores: == y ===. == convierte los tipos antes de comparar (por eso "5" == 5 da true, aunque uno sea texto y el otro número). === NO convierte nada: compara tipo y valor a la vez, y es casi siempre la opción correcta para evitar sorpresas.
Para combinar más de una condición, se usan los operadores lógicos && (Y — las dos deben cumplirse) y || (O — alcanza con que se cumpla una).
==, pero es estricto con los tipos (no convierte texto en número). El === de JavaScript es el que se comporta como el == que ya conoces de Python. Y donde escribías and / or, en JS se escribe && / ||.const edad = 13;
const tieneEntrada = true;
if (edad >= 12 && tieneEntrada === true) {
console.log('Puede entrar');
} else {
console.log('No puede entrar');
}
🧩 ¿Lo entendiste? · Repaso rápido
🧩 Ahora practica
🧹 Normalizar texto antes de comparar
Si comparas la respuesta de un estudiante directamente con ===, un espacio de más o una mayúscula de más hacen que una respuesta correcta se marque como error. Por eso, antes de comparar, conviene normalizar el texto.
.trim() saca los espacios al principio y al final del texto. .toLowerCase() convierte todo a minúsculas, así "Rojo", "ROJO" y "rojo" se comparan igual.
.trim().toLowerCase() primero, tanto a la respuesta del estudiante como a la respuesta correcta.const respuesta = " Rojo "; const normalizada = respuesta.trim().toLowerCase(); // normalizada === "rojo"
🧩 ¿Lo entendiste? · Completa el código
Completa con el método correcto en cada espacio.
const normalizada = respuesta.().();
🧩 Ahora practica
Funciones y arrays: organizar y reutilizar
Ya sabemos reaccionar a eventos y comparar respuestas. Ahora conviene juntar esa lógica en una función propia, y ver cómo trabajar con varias respuestas válidas a la vez usando arrays.
🧩 Declarar funciones: parámetros y return
Una función se declara con function nombre(parámetros) { ... }. Dentro, return devuelve un valor y termina la ejecución de la función en ese punto.
¿Por qué conviene encapsular la corrección en una función? Porque el evento (el clic, el submit) necesita un solo lugar al que llamar cuando ocurre, y esa misma lógica de corrección la vas a querer reutilizar — por ejemplo, para revisar automáticamente sin esperar a que el estudiante haga clic, o para probarla tú mismo antes de publicar la actividad. Si el código de corrección estuviera suelto, tendrías que copiarlo cada vez.
def nombre(parámetros): ... return valor. Solo cambia la sintaxis (llaves en vez de indentación, y hay que escribir function).function duplicar(n) {
return n * 2;
}
const resultado = duplicar(21);
// resultado === 42
🧩 Ahora practica
📦 Arrays y el método .includes()
Un array se crea con corchetes: const respuestasValidas = ['rojo', 'colorado'];. Es útil cuando una actividad acepta más de una respuesta correcta.
array.includes(valor) devuelve true si valor está dentro del array, y false si no. Combinado con la normalización que ya viste, queda algo así: respuestasValidas.includes(respuestaNormalizada).
array.includes(valor) es exactamente lo mismo que valor in lista. Solo cambia el orden: en JS, el array va primero.const respuestasValidas = ['rojo', 'colorado'];
const respuestaEstudiante = 'colorado';
if (respuestasValidas.includes(respuestaEstudiante)) {
console.log('Correcto');
}
🧩 Ahora practica
Llevar el puntaje
Ya puedes detectar si una respuesta es correcta. Ahora falta la última pieza: sumar o restar puntos de forma prolija, sin que el puntaje quede nunca en negativo.
➕ Operadores compuestos: += y -=
puntaje += 5 es una forma abreviada de escribir puntaje = puntaje + 5. De la misma manera, puntaje -= 3 equivale a puntaje = puntaje - 3.
Son más cortos y, sobre todo, dejan más clara la intención: "sumale esto al puntaje" en vez de "el puntaje es el puntaje más esto".
let puntaje = 10; puntaje += 5; // puntaje ahora es 15 puntaje -= 3; // puntaje ahora es 12
🧩 Ahora practica
🛡️ Math.max(): que el puntaje nunca baje de 0
Si vas restando puntos por cada error, el puntaje puede terminar en negativo — algo que confunde más de lo que ayuda. Math.max(a, b) devuelve el mayor de los dos valores que le pases.
Por eso, para penalizar sin bajar nunca de 0, se escribe puntaje = Math.max(0, puntaje - 5): si puntaje - 5 da negativo, Math.max devuelve 0 en su lugar; si da positivo, devuelve ese valor.
Math.max(0, puntaje - N) — es el que vas a usar en la Práctica Integrada para que el puntaje nunca sea negativo.let puntaje = 2; puntaje = Math.max(0, puntaje - 5); // puntaje === 0 (no -3)
🧩 Ahora practica
Práctica Integrada: corregirActividad()
Esta es la pieza que necesitas para tu Sprint 3: una función que junta todo lo del recurso — evento, comparación normalizada, feedback visual y puntaje — en un solo lugar reutilizable.
🎯 Misión: programar corregirActividad()
Tienes una pregunta con un campo de respuesta y un botón "Corregir". Completa la función corregirActividad() siguiendo los 4 pasos siempre presentes en este patrón:
.trim().toLowerCase()).=== o .includes()).classList) que muestre si estuvo bien o mal.+= / -=, protegido con Math.max(0, ...) para que nunca baje de 0.addEventListener('click', corregirActividad). Si el código de corrección no estuviera encapsulado en una función, no habría nada que conectar al evento.👀 Primero, mira cómo se construye paso a paso
✍️ Ahora, prográmala tú mismo
Glosario
Todos los términos de este recurso, para repasar. Toca una tarjeta para girarla y ver la definición.
No encontré ningún término con esa búsqueda.