Curso de programación GRATIS Modulo III: Desarrollo Web Parte III - JavaScript y Proyecto final.
JS · M3 · Desarrollo Web
0%
Módulo 3 · JavaScript
✅ Módulo 3 anterior
🚀 Proyecto del módulo
Sitio web profesional completo
Completa L8–L11 para desbloquearlo
Módulo 3 · Desarrollo Web · JavaScript · 2026
JavaScript: dale vida e interactividad a tu sitio
El último gran bloque del Módulo 3. Aprenderás a manejar datos con variables, responder a las acciones del usuario con eventos, manipular la página en tiempo real con el DOM, y comunicarte con servidores usando Fetch API. Al final, unirás HTML + CSS + JS en tu primer sitio web profesional completo.
4Lecciones
1Proyecto final
4Mini quizzes
∞Tu portafolio
🔖 Marcadores
Sin marcadores — usa el botón dorado en cualquier lección.
L8
Fundamentos
Variables: donde JavaScript guarda información
JavaScript es el lenguaje que convierte una página estática en una aplicación interactiva. Todo empieza con las variables: espacios con nombre donde guardas datos para usarlos después — un nombre de usuario, el resultado de un cálculo, el contenido de un formulario, etc.
📦
Analogía: las variables son cajas con etiqueta
Imagina cajas de almacenamiento con una etiqueta escrita a mano. let edad = 25 es como escribir "edad" en una etiqueta y meter el número 25 dentro de esa caja. Más adelante puedes abrir la caja, ver qué hay, o incluso cambiar el contenido. const es como una caja selladas con cinta — una vez que metes algo, no puedes cambiarlo (aunque si es un objeto, sí puedes modificar lo que hay dentro de él).
let, const y var: ¿cuál usar?
JavaScript — Declaración de variables
// ── let: variable que SÍ puede reasignarse ──letedad = 25;
edad = 26; // ✅ funciona — let permite reasignar// ── const: variable que NO puede reasignarse ──constPI = 3.1416;
PI = 4; // ❌ Error: Assignment to constant variable// ── const con objetos/arrays: el contenido SÍ es mutable ──constusuario = { nombre: "Ana", edad: 25 };
usuario.edad = 26; // ✅ funciona — modificas una propiedad, no reasignasusuario = {}; // ❌ Error — esto SÍ es reasignar// ── var: la forma antigua (evitar en código nuevo) ──varnombre = "Carlos"; // funciona, pero tiene problemas de "scope"// var no respeta los bloques {} — usa let/const siempre
✅ Regla práctica
Usa const por defecto — la mayoría de tus variables no necesitan cambiar. Usa let solo cuando sepas que el valor cambiará (contadores, acumuladores, valores que se actualizan). Evita var por completo en código nuevo: es la versión antigua de JavaScript y tiene comportamientos confusos con el alcance (scope).
Tipos de datos primitivos
JavaScript — Los tipos de datos básicos
// ── String: texto, entre comillas simples, dobles o backticks ──constnombre = "Ana García";
constsaludo = `Hola, ${nombre}`; // template literal — interpola variables// ── Number: enteros y decimales, sin diferencia ──constedad = 25;
constprecio = 19.99;
// ── Boolean: verdadero o falso ──constactivo = true;
constcompletado = false;
// ── Array: lista ordenada de valores ──constcolores = ["rojo", "verde", "azul"];
colores[0]; // "rojo" — los índices empiezan en 0colores.length; // 3// ── Object: pares clave-valor ──constproducto = {
nombre: "Laptop",
precio: 899.99,
disponible: true,
tags: ["tech", "oferta"]
};
producto.nombre; // "Laptop" — notación de puntoproducto["precio"]; // 899.99 — notación de corchetes// ── undefined, null: ausencia de valor ──letsinValor; // undefined — declarado pero sin asignarletvacio = null; // null — "intencionalmente sin valor"// ── typeof: para saber el tipo de un valor ──typeof"hola"; // "string"typeof42; // "number"typeoftrue; // "boolean"
Operadores y funciones
JavaScript — Operadores, condicionales y funciones
// ── Operadores aritméticos ──10+5; // 1510%3; // 1 (residuo)10-5; // 52**3; // 8 (potencia)10*5; // 5010/5; // 2// ── Operadores de comparación ──5===5; // true — igualdad estricta (usa siempre ===)5=="5"; // true — igualdad débil (convierte tipos, evitar)5!==3; // true — diferente, estricto5>3; // true// ── Operadores lógicos ──true&&false; // false — Y (AND)true||false; // true — O (OR)!true; // false — NO (NOT)// ── Condicionales ──constedad = 17;
if (edad>=18) {
console.log("Eres mayor de edad");
} else {
console.log("Eres menor de edad");
}
// ── Operador ternario: if/else en una línea ──constmensaje = edad>=18?"Adulto":"Menor";
// ── Funciones: bloques de código reutilizables ──functionsaludar(nombre) {
return`¡Hola, ${nombre}!`;
}
saludar("Ana"); // "¡Hola, Ana!"// ── Arrow functions: sintaxis moderna y compacta ──constsumar = (a, b) =>a+b;
sumar(3, 4); // 7
Métodos de array más usados
JavaScript — map, filter, forEach: el trío esencial
constproductos = [
{ nombre: "Laptop", precio: 899, stock: 3 },
{ nombre: "Mouse", precio: 25, stock: 0 },
{ nombre: "Teclado", precio: 60, stock: 12 }
];
// ── forEach: ejecuta una función por cada elemento ──productos.forEach(p=> {
console.log(`${p.nombre}: $${p.precio}`);
});
// ── map: transforma cada elemento y devuelve un NUEVO array ──constnombres = productos.map(p=>p.nombre);
// ["Laptop", "Mouse", "Teclado"]// ── filter: devuelve un NUEVO array con los que cumplen la condición ──constdisponibles = productos.filter(p=>p.stock>0);
// [{nombre:"Laptop",...}, {nombre:"Teclado",...}]// ── find: devuelve el PRIMER elemento que cumple la condición ──constlaptop = productos.find(p=>p.nombre==="Laptop");
// ── reduce: combina todos los elementos en un solo valor ──consttotal = productos.reduce((acc, p) =>acc+p.precio, 0);
// 984 — suma de todos los precios
Demo interactiva: variables en acción
▶ Calculadora simple — observa cómo se usan variables y operadores
Resultado: —
🧠 Quiz: ¿Cuál es la principal diferencia entre let y const al declarar una variable?
L9
Fundamentos
Eventos: cuando el usuario hace algo, tu código responde
Un evento es una acción que ocurre en la página: un clic, una tecla presionada, el envío de un formulario, el desplazamiento de la pantalla. JavaScript puede "escuchar" estos eventos y ejecutar código en respuesta. Esto es lo que hace que una página deje de ser un documento estático y se convierta en una aplicación interactiva.
🔔
Analogía: los eventos son timbres con un mayordomo esperando
Imagina un timbre en la puerta. El mayordomo (tu código) no hace nada hasta que alguien presiona el timbre (el evento). En cuanto eso pasa, el mayordomo ejecuta su tarea: abrir la puerta (la función). addEventListener('click', funcion) es literalmente decirle al elemento: "cuando alguien haga clic en ti, ejecuta esta función". El navegador se encarga de "escuchar" constantemente.
addEventListener: la forma correcta de escuchar eventos
JavaScript — Sintaxis básica de eventos
// ── Sintaxis general ──elemento.addEventListener('tipo-de-evento', funcion);
// ── Ejemplo: botón con clic ──constboton = document.querySelector('#mi-boton');
boton.addEventListener('click', function() {
console.log('¡Hiciste clic!');
});
// ── Con arrow function (más común hoy) ──boton.addEventListener('click', () => {
alert('¡Hola!');
});
// ── El objeto "event": información sobre lo que pasó ──boton.addEventListener('click', (event) => {
console.log(event.target); // el elemento que disparó el eventoconsole.log(event.type); // "click"event.preventDefault(); // evita el comportamiento por defecto (ej: enviar form)
});
Tipos de eventos más comunes
Evento
Se dispara cuando…
Ejemplo de uso
click
El usuario hace clic en un elemento
Botones, links, tarjetas
dblclick
Doble clic
Editar en línea
input
El valor de un input cambia en tiempo real (cada letra)
Búsqueda en vivo, contadores de caracteres
change
Un input pierde el foco con valor cambiado
Selects, checkboxes
submit
Se envía un formulario
Validar antes de enviar
keydown / keyup
Se presiona / suelta una tecla
Atajos de teclado, juegos
mouseenter / mouseleave
El mouse entra / sale de un elemento
Tooltips, menús hover
scroll
Se hace scroll en la página
Navbar que cambia al hacer scroll
load
La página termina de cargar
Inicializar la app
resize
Cambia el tamaño de la ventana
Layouts adaptativos con JS
Demo interactiva: eventos en vivo
▶ Eventos de clic y mouse
Haz clic en la caja — cada clic dispara el evento click y cambia el color con JS.
Clics: 0
▶ Evento "input" — reacciona a cada letra que escribes
Caracteres: 0 | Palabras: 0
Formularios: validar antes de enviar
JavaScript — Validar un formulario con evento submit
constform = document.querySelector('#form-contacto');
form.addEventListener('submit', (event) => {
event.preventDefault(); // evita que la página se recargueconstemail = document.querySelector('#email').value;
constmensaje = document.querySelector('#mensaje').value;
// Validación simpleif (!email.includes('@')) {
alert('Ingresa un email válido');
return;
}
if (mensaje.length<10) {
alert('El mensaje debe tener al menos 10 caracteres');
return;
}
console.log('Formulario válido, enviando...');
// aquí iría el fetch() para enviar al servidor (lección 11)
});
⚠ Propagación de eventos: bubbling
Cuando haces clic en un elemento, el evento "burbujea" hacia arriba por todos sus elementos padre. Si tienes un <div> con un <button> dentro y ambos tienen click listeners, hacer clic en el botón dispara ambos eventos (botón primero, luego el div). Usa event.stopPropagation() si necesitas evitar esto. Es uno de los comportamientos que más confunde a quienes empiezan.
🧠 Quiz: Quieres que, mientras el usuario escribe en un campo de búsqueda, se filtren resultados en tiempo real con cada letra. ¿Qué evento usarías?
L10
Intermedio
DOM: manipular la página en tiempo real
El DOM (Document Object Model) es la representación en memoria de tu HTML que el navegador construye y que JavaScript puede leer y modificar. Cada etiqueta HTML se convierte en un "nodo" del árbol DOM. Con JavaScript puedes seleccionar esos nodos, leer su contenido, cambiar estilos, añadir o quitar elementos — todo sin recargar la página.
🎭
Analogía: el DOM es el escenario, JS es el director
El HTML es como el guion de una obra de teatro: define qué personajes existen y dónde empiezan. El DOM es el escenario real con los actores ya colocados. JavaScript es el director que, durante la función, puede mover actores de lugar, cambiarles el vestuario, hacer aparecer o desaparecer personajes — todo en vivo, sin reescribir el guion ni empezar de nuevo.
Seleccionar elementos
JavaScript — Selectores del DOM
// ── querySelector: el más usado — devuelve el PRIMER elemento que coincide ──document.querySelector('#mi-id'); // por IDdocument.querySelector('.mi-clase'); // por clasedocument.querySelector('button'); // por etiquetadocument.querySelector('nav a.activo'); // selector CSS complejo// ── querySelectorAll: devuelve TODOS los que coinciden (NodeList) ──consttarjetas = document.querySelectorAll('.tarjeta');
tarjetas.forEach(tarjeta=> {
console.log(tarjeta);
});
// ── Otros selectores clásicos (menos usados hoy) ──document.getElementById('mi-id');
document.getElementsByClassName('mi-clase');
Árbol DOM: cómo se ve por dentro
🌳 querySelector('#tarjeta-2') encuentra el nodo resaltado
<main>contenedor principal
<div class="grid">contenedor de tarjetas
<div id="tarjeta-1">tarjeta 1
<div id="tarjeta-2">← este es el nodo seleccionado
consttitulo = document.querySelector('#titulo');
// ── textContent: leer/cambiar SOLO texto (seguro) ──console.log(titulo.textContent); // lee el texto actualtitulo.textContent = 'Nuevo título'; // cambia el texto// ── innerHTML: leer/cambiar incluyendo etiquetas HTML ──titulo.innerHTML = `Hola mundo`;
// ⚠ cuidado con innerHTML + datos de usuarios: riesgo de XSS// ── classList: añadir, quitar, alternar clases CSS ──titulo.classList.add('activo'); // añade la clasetitulo.classList.remove('oculto'); // quita la clasetitulo.classList.toggle('dark-mode'); // añade si no está, quita si estátitulo.classList.contains('activo'); // true/false// ── style: modificar CSS directamente (uso ocasional) ──titulo.style.color = 'red';
titulo.style.display = 'none';
// ── atributos ──titulo.setAttribute('data-id', '42');
titulo.getAttribute('data-id'); // "42"
Crear y eliminar elementos dinámicamente
JavaScript — createElement, append, remove
constlista = document.querySelector('#lista-tareas');
// ── Crear un nuevo elemento ──constnuevaTarea = document.createElement('li');
nuevaTarea.textContent = 'Aprender Fetch API';
nuevaTarea.classList.add('tarea');
// ── Añadirlo al DOM ──lista.appendChild(nuevaTarea); // al finallista.prepend(nuevaTarea); // al principio// ── Eliminar un elemento ──nuevaTarea.remove();
// ── Patrón completo: agregar tarea desde un input ──constinput = document.querySelector('#nueva-tarea');
constboton = document.querySelector('#agregar');
boton.addEventListener('click', () => {
if (input.value.trim() ==='') return;
constli = document.createElement('li');
li.textContent = input.value;
lista.appendChild(li);
input.value = ''; // limpiar el input
});
Demo interactiva: lista de tareas con el DOM
▶ Mini to-do list — createElement + appendChild + remove
💡 Rendimiento: minimiza las consultas al DOM
Cada llamada a querySelector o cambio en el DOM tiene un costo. Si necesitas usar el mismo elemento varias veces, guárdalo en una variable una sola vez en lugar de volver a buscarlo. Si vas a insertar muchos elementos, considera construir el HTML como string o usar DocumentFragment y hacer un solo appendChild al final, en lugar de uno por cada elemento.
🧠 Quiz: ¿Cuál es la diferencia principal entre textContent e innerHTML?
L11
Avanzado
Fetch API: tu sitio habla con el mundo
Hasta ahora todo ha vivido dentro del navegador. La Fetch API permite que JavaScript se comunique con servidores externos: obtener datos de una API, enviar formularios sin recargar la página, cargar contenido dinámico. Es la puerta de entrada a aplicaciones web reales — desde un clima en vivo hasta un feed de redes sociales.
📬
Analogía: fetch es enviar una carta y esperar respuesta
Imagina que envías una carta pidiendo información (la petición/request) a una oficina (el servidor). No te quedas parado en el buzón esperando — sigues con tu vida (el código sigue ejecutándose) hasta que llega la respuesta (la promesa se resuelve). Cuando llega, abres el sobre (procesas el JSON) y actúas según el contenido. fetch() es asíncrono: no bloquea el resto de tu programa mientras espera.
Anatomía de una petición fetch
🔄 Flujo de una petición Fetch API
Navegador (cliente)
→
fetch('https://api.ejemplo.com/datos') — se envía una petición HTTP
Servidor / API
→
El servidor procesa la petición y responde con datos (normalmente JSON)
Navegador (cliente)
→
.then(res => res.json()) — se convierte la respuesta a un objeto JS usable
fetch con async/await (sintaxis moderna)
JavaScript — GET request con async/await
// ── async/await: forma moderna y más legible que .then() ──asyncfunctionobtenerUsuarios() {
try {
constrespuesta = awaitfetch('https://jsonplaceholder.typicode.com/users');
// Verificar que la respuesta sea exitosa (código 200-299)if (!respuesta.ok) {
thrownewError(`Error ${respuesta.status}: ${respuesta.statusText}`);
}
constusuarios = awaitrespuesta.json(); // convierte la respuesta a JSONconsole.log(usuarios);
returnusuarios;
} catch (error) {
console.error('Algo salió mal:', error);
}
}
obtenerUsuarios();
// ── Equivalente con .then() / .catch() (forma anterior) ──fetch('https://jsonplaceholder.typicode.com/users')
.then(respuesta=>respuesta.json())
.then(usuarios=>console.log(usuarios))
.catch(error=>console.error(error));
POST: enviar datos al servidor
JavaScript — Enviar datos de un formulario con POST
asyncfunctionenviarFormulario(datos) {
try {
constrespuesta = awaitfetch('https://api.ejemplo.com/contacto', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(datos) // convierte el objeto JS a texto JSON
});
if (!respuesta.ok) {
thrownewError('Error al enviar el formulario');
}
constresultado = awaitrespuesta.json();
console.log('Enviado:', resultado);
} catch (error) {
console.error(error);
}
}
// ── Uso real: combinando con un evento submit ──constform = document.querySelector('#form-contacto');
form.addEventListener('submit', async (event) => {
event.preventDefault();
constdatos = {
nombre: document.querySelector('#nombre').value,
email: document.querySelector('#email').value,
mensaje: document.querySelector('#mensaje').value
};
awaitenviarFormulario(datos);
});
Demo interactiva: consumir una API real
▶ Fetch en vivo — obtiene datos de una API pública
Presiona el botón para hacer una petición fetch real a una API pública (jsonplaceholder.typicode.com)
Estados de carga: loading, error, éxito
JavaScript — Manejar estados de UI durante un fetch
constcontenedor = document.querySelector('#resultados');
asyncfunctioncargarDatos() {
// 1. Estado de cargacontenedor.innerHTML = `<p>Cargando...</p>`;
try {
constres = awaitfetch('https://api.ejemplo.com/productos');
if (!res.ok) thrownewError('No se pudieron cargar los productos');
constproductos = awaitres.json();
// 2. Estado de éxito — renderizar resultadoscontenedor.innerHTML = productos
.map(p=>`<div class="card">${p.nombre}</div>`)
.join('');
} catch (error) {
// 3. Estado de errorcontenedor.innerHTML = `<p class="error">${error.message}</p>`;
}
}
✅ Buenas prácticas con Fetch API
(1) Siempre usa try/catch — las peticiones de red fallan (sin internet, servidor caído, CORS). (2) Verifica response.ok — fetch NO lanza error en respuestas 404 o 500, solo si la red falla completamente. (3) Muestra siempre un estado de carga al usuario. (4) Nunca expongas API keys secretas en el JavaScript del navegador — son visibles para cualquiera. (5) Usa JSON.stringify() al enviar y .json() al recibir.
🧠 Quiz: Tu fetch a una API devuelve un código 404 (no encontrado). ¿Qué pasa con tu bloque try/catch si solo usas await fetch(url) sin verificar response.ok?
🏆
Proyecto Final
Proyecto Final: tu sitio web profesional completo
Ha llegado el momento de unir todo el Módulo 3. Vas a construir un sitio web de una sola página (one-page) tipo portafolio o landing page, aplicando absolutamente todo lo aprendido: HTML semántico, formularios, multimedia, SEO, Flexbox, Grid, Responsive Design, variables, eventos, DOM y Fetch API.
🚀 Proyecto Final del Módulo 3
Sitio web profesional completo: HTML + CSS + JavaScript trabajando juntos
✅ HTML semántico✅ Formularios✅ Flexbox + Grid✅ Responsive✅ DOM + Eventos✅ Fetch API📤 Sitio completo
Vista previa de lo que vas a construir
🔒 tu-nombre.dev
Tu Nombre
InicioProyectosSobre míContacto
Desarrollador(a) Web Frontend
HTML · CSS · JavaScript — Disponible para proyectos freelance
Mis proyectos
🧮Calculadora
📦Inventario
✅To-do List
🌐API Clima
Contáctame
Estructura de archivos del proyecto
Estructura del proyecto — Sitio Web Profesional
mi-sitio-web/│├── index.html# estructura: nav, hero, proyectos, sobre mí, contacto, footer├── css/│ └── styles.css# Flexbox + Grid + Media Queries (mobile first)├── js/│ ├── app.js# inicialización, eventos generales│ ├── theme.js# modo oscuro con localStorage│ ├── form.js# validación y envío del formulario│ └── api.js# fetch a una API externa (ej: clima, frases, GitHub)├── assets/│ ├── images/# fotos optimizadas en WebP│ └── icons/# favicon, iconos SVG└── README.md# documentación del proyecto para GitHub
Paso a paso: construye tu sitio
1
Estructura HTML semántica
Crea index.html con <header> (nav), <main> con varias <section> (hero, proyectos, sobre mí), y <footer>. Incluye meta tags de SEO (title, description, viewport, Open Graph) desde el inicio.
2
Layout con Grid y Flexbox
Usa Grid para la estructura general de la página y la galería de proyectos (repeat(auto-fit, minmax(...))). Usa Flexbox para la navbar, las tarjetas individuales y el footer.
3
Hazlo responsivo
Diseña Mobile First: una columna en móvil, navbar con menú hamburguesa. Con media queries en 768px y 1024px, expande a múltiples columnas y muestra el menú completo. Verifica con DevTools en al menos 3 tamaños.
4
Interactividad con JS: tema oscuro
Agrega un botón que alterne classList.toggle('dark-mode') en el <body>, y guarda la preferencia para que persista al recargar (usando localStorage en tu propio sitio, o cookies si está embebido en Blogger).
5
Formulario de contacto funcional
Valida el formulario con JavaScript antes de enviarlo (campos vacíos, formato de email). Muestra mensajes de error o éxito dinámicamente en el DOM sin recargar la página.
6
Consume una API real con Fetch
Agrega una sección dinámica: una frase motivacional aleatoria, el clima de tu ciudad, o tus repositorios públicos de GitHub (api.github.com/users/TU_USUARIO/repos). Maneja los tres estados: cargando, éxito y error.
7
Publica en GitHub Pages
Sube el proyecto a tu repositorio (aplicando el flujo de branches + PR del Módulo 2), y activa GitHub Pages en Settings → Pages para obtener una URL pública gratuita: tu-usuario.github.io/mi-sitio-web.
Ejemplo: tema oscuro con JS
JavaScript — theme.js: alternar y recordar el tema
constbtnTema = document.querySelector('#btn-tema');
constbody = document.body;
// Cargar preferencia guardada al iniciarconsttemaGuardado = localStorage.getItem('tema');
if (temaGuardado==='oscuro') {
body.classList.add('dark-mode');
}
// Alternar al hacer clicbtnTema.addEventListener('click', () => {
body.classList.toggle('dark-mode');
constesOscuro = body.classList.contains('dark-mode');
localStorage.setItem('tema', esOscuro?'oscuro':'claro');
});
Lista de verificación final
✅
HTML semántico completo — header, nav, main con secciones, footer; un solo h1; meta tags SEO.
✅
Layout con Grid y Flexbox — galería de proyectos responsiva, navbar con Flexbox.
✅
Totalmente responsivo — probado en móvil, tablet y desktop; mobile first.
✅
Tema claro/oscuro funcional con JavaScript y persistencia.
✅
Formulario validado con JS, mostrando feedback al usuario sin recargar la página.
✅
Al menos una llamada a Fetch API con manejo de carga, éxito y error.
✅
Imágenes optimizadas con alt, loading="lazy" y formato WebP.
✅
Publicado online — GitHub Pages, Netlify o Vercel, con URL compartible.
🎓 Lo que acabas de lograr
Si completaste este proyecto, tienes en tu portafolio un sitio web real, responsivo e interactivo construido desde cero — sin frameworks, sin atajos, entendiendo cada línea de código. Esa base es exactamente lo que necesitas antes de saltar a frameworks como React o Vue: entenderás qué están haciendo por debajo, no solo cómo usarlos.
🚀 ¿Qué sigue? Módulo 4
Con HTML, CSS y JavaScript dominados, el Módulo 4 dará el salto a frameworks modernos de frontend: componentes, estado, y cómo estas herramientas construyen sobre exactamente los conceptos que ya conoces — el DOM, los eventos y fetch, pero de forma más estructurada y escalable.
🏆
¡Módulo 3 completado!
Dominas Desarrollo Web completo: HTML semántico, formularios, multimedia y SEO; CSS con Flexbox, Grid y Responsive Design; y JavaScript con variables, eventos, DOM y Fetch API. Construiste tu primer sitio web profesional completo.
El Módulo 4 (Frameworks modernos de frontend) te espera.
0 Comentarios