Ciencias de la Computación · Ceibal · Parte 2 de 2: Lógica y Corrección
🖱️ Eventos
Sección 1 de 6

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.

📘 Este es el Recurso 2 de 2 sobre JavaScript y el DOM: acá vemos cómo reaccionar a eventos, tomar decisiones con condicionales, encapsular la corrección en funciones y llevar el puntaje. El Recurso 1 cubrió el DOM, la selección de elementos y cómo leer y crear contenido — lo vas a seguir usando todo el tiempo acá.

🖱️ 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 un programa que corre de arriba hacia abajo y termina apenas llega al final. Acá el código sigue "vivo", esperando que ocurra algo — 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!');
});
tiempo addEventListener('click', fn) engancha fn… pero NO la ejecuta se carga la página ⏳ esperando… ▶ se ejecuta fn 🖱️ clic ⏳ esperando… ▶ se ejecuta fn 🖱️ otro clic
El código se engancha una sola vez y después queda esperando: la función corre cada vez que ocurre el clic, no antes.
👀 Ejemplo guiado · Primero míralo resuelto, paso a paso
🧩 ¿Lo entendiste? · Practica
JS script.js

                  
                

⌨️ 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.

⚠️ Si te olvidas de 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.
"input" se dispara con CADA tecla que se escribe r| ro| roj| rojo| ⚡ input ⚡ input ⚡ input ⚡ input 4 teclas = 4 eventos "submit" se dispara UNA vez, al enviar el formulario Enviar ▶ sin preventDefault() → 🔄 se recarga y pierdes el puntaje con event.preventDefault() → ✔ todo sigue en su lugar
input sirve para reaccionar mientras se escribe; submit, para corregir al final — siempre con event.preventDefault().
👀 Ejemplo guiado · Primero míralo resuelto, paso a paso
🧩 ¿Lo entendiste? · Repaso rápido
🧩 Ahora practica
JS script.js

                  
                

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 { ... } evalúa la condición entre paréntesis: si es verdadera, ejecuta el bloque que sigue entre llaves; si no, ejecuta el bloque de else.

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).

const edad = 13;
const tieneEntrada = true;

if (edad >= 12 && tieneEntrada === true) {
  console.log('Puede entrar');
} else {
  console.log('No puede entrar');
}
edad = 13 · tieneEntrada = true edad >= 12 && tieneEntrada === true ¿es verdadera? true ✔ "Puede entrar" se ejecuta el bloque if false ✖ "No puede entrar" bloque else && → las DOS condiciones deben ser true || → alcanza con que UNA sea true "5" == 5 → true · "5" === 5 → false
Con edad 13 y entrada, las dos partes del && son verdaderas: el programa toma el camino del if y salta el else.
👀 Ejemplo guiado · Primero míralo resuelto, paso a paso
🧩 ¿Lo entendiste? · Repaso rápido
🧩 Ahora practica
JS script.js

                  
                

🧹 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.

Regla práctica: antes de comparar una respuesta escrita por el usuario, siempre aplica .trim().toLowerCase() primero, tanto a la respuesta del estudiante como a la respuesta correcta.
const respuesta = "  Rojo  ";
const normalizada = respuesta.trim().toLowerCase();
// normalizada === "rojo"
"␣␣Rojo␣␣" .trim() "Rojo" .toLowerCase() "rojo" === "rojo" ✔ true lo que escribió sin espacios en minúsculas ¡coincide! Sin normalizar: "␣␣Rojo␣␣" === "rojo" → false ✖ ␣ = un espacio en blanco
Normalizar es limpiar antes de comparar: así una respuesta correcta no se marca mal por un espacio o una mayúscula.
👀 Ejemplo guiado · Primero míralo resuelto, paso a paso
🧩 ¿Lo entendiste? · Completa el código
Completar espacios
const normalizada = respuesta.().();
🧩 Ahora practica
JS script.js

                  
                

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.

function duplicar(n) {
  return n * 2;
}

const resultado = duplicar(21);
// resultado === 42
21 argumento entra function duplicar(n) el parámetro n recibe 21 return n * 2; 21 * 2 = 42 → sale y la función termina return 42 valor devuelto const resultado = duplicar(21); // resultado === 42
Una función es como una máquina: le das un dato por el parámetro, hace su trabajo y te devuelve un resultado con return.
👀 Ejemplo guiado · Primero míralo resuelto, paso a paso
🧩 Ahora practica
JS script.js

                  
                

📦 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).

const respuestasValidas = ['rojo', 'colorado'];
const respuestaEstudiante = 'colorado';

if (respuestasValidas.includes(respuestaEstudiante)) {
  console.log('Correcto');
}
respuestasValidas 'rojo' 'colorado' 0 1 'azul' no está en el array respuestasValidas.includes('colorado') → true ✔ respuestasValidas.includes('azul') → false ✖
.includes() revisa el array de punta a punta y responde con una sola palabra: true si encontró el valor, false si no.
👀 Ejemplo guiado · Primero míralo resuelto, paso a paso
🧩 Ahora practica
JS script.js

                  
                

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
puntaje 10 puntaje += 5 = puntaje + 5 puntaje 15 puntaje -= 3 = puntaje - 3 puntaje 12 Se lee como una orden: «súmale 5 al puntaje» · «réstale 3 al puntaje»
La misma variable va cambiando de valor: cada operador compuesto toma el valor actual y lo actualiza.
👀 Ejemplo guiado · Primero míralo resuelto, paso a paso
🧩 Ahora practica
JS script.js

                  
                

🛡️ 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.

🛡️ Este patrón — 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)
negativos ✖ -5-4-3-2-1012345 piso: 0 puntaje = 2 2 - 5 = -3 Math.max(0, -3) → 0
Math.max(0, …) funciona como un piso: si la resta cae en negativo, devuelve 0; si no, deja pasar el resultado.
👀 Ejemplo guiado · Primero míralo resuelto, paso a paso
🧩 Ahora practica
JS script.js

                  
                

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()

Toda corrección automática sigue siempre el mismo patrón de 4 pasos:

1
Leer la respuesta desde el DOM (y normalizarla con .trim().toLowerCase()).
2
Comparar contra la respuesta o respuestas correctas (con === o .includes()).
3
Dar feedback visual: un mensaje y una clase (classList) que muestre si estuvo bien o mal.
4
Ajustar el puntaje con += / -=, protegido con Math.max(0, ...) para que nunca baje de 0.
🖱️ clic en Corregir corregirActividad() 1 Leer .value .trim() .toLowerCase() 2 Comparar === .includes() 3 Feedback textContent classList 4 Puntaje += / -= Math.max(0, …)
Un solo clic dispara toda la cadena: la función recorre los 4 pasos en orden, cada uno con las herramientas que ya aprendiste.
💡 Por qué una función y no código suelto: el botón "Corregir" necesita un solo lugar al que llamar cuando se hace clic — 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

0 / 4

  

✍️ Ahora, prográmala tú mismo

JS script.js

      
    

Glosario

Todos los términos de este recurso, para repasar. Toca una tarjeta para girarla y ver la definición.

🔍
Sección 1 de 6