En esta sección, vamos a poner en práctica todo lo que hemos aprendido a lo largo del curso construyendo un proyecto completo en JavaScript. Este proyecto servirá como una excelente oportunidad para consolidar tus conocimientos y habilidades. Vamos a seguir un enfoque paso a paso para asegurarnos de que cada parte del proyecto esté bien entendida y funcional.
- Definición del Proyecto
Objetivo del Proyecto
Vamos a construir una aplicación web de gestión de tareas (To-Do List). La aplicación permitirá a los usuarios:
- Añadir nuevas tareas.
- Marcar tareas como completadas.
- Eliminar tareas.
- Filtrar tareas por estado (todas, completadas, pendientes).
Tecnologías Utilizadas
- HTML y CSS para la estructura y el diseño de la interfaz.
- JavaScript para la lógica de la aplicación.
- LocalStorage para el almacenamiento de datos en el navegador.
- Estructura del Proyecto
Estructura de Archivos
Vamos a organizar nuestro proyecto de la siguiente manera:
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>To-Do List</title> <link rel="stylesheet" href="styles/styles.css"> </head> <body> <div class="container"> <h1>To-Do List</h1> <form id="task-form"> <input type="text" id="task-input" placeholder="Add a new task" required> <button type="submit">Add Task</button> </form> <ul id="task-list"></ul> <div class="filters"> <button id="all">All</button> <button id="completed">Completed</button> <button id="pending">Pending</button> </div> </div> <script src="scripts/app.js"></script> </body> </html>
styles/styles.css
body { font-family: Arial, sans-serif; background-color: #f4f4f4; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; } .container { background: #fff; padding: 20px; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); width: 300px; } h1 { text-align: center; } form { display: flex; justify-content: space-between; } input[type="text"] { width: 70%; padding: 10px; border: 1px solid #ccc; border-radius: 5px; } button { padding: 10px; border: none; background: #28a745; color: #fff; border-radius: 5px; cursor: pointer; } button:hover { background: #218838; } ul { list-style: none; padding: 0; } li { display: flex; justify-content: space-between; padding: 10px; border-bottom: 1px solid #ccc; } li.completed { text-decoration: line-through; color: #888; } .filters { display: flex; justify-content: space-around; margin-top: 20px; } .filters button { background: #007bff; color: #fff; border: none; padding: 5px 10px; border-radius: 5px; cursor: pointer; } .filters button:hover { background: #0056b3; }
scripts/app.js
document.addEventListener('DOMContentLoaded', () => { const taskForm = document.getElementById('task-form'); const taskInput = document.getElementById('task-input'); const taskList = document.getElementById('task-list'); const filters = document.querySelectorAll('.filters button'); let tasks = JSON.parse(localStorage.getItem('tasks')) || []; const renderTasks = (filter = 'all') => { taskList.innerHTML = ''; const filteredTasks = tasks.filter(task => { if (filter === 'all') return true; if (filter === 'completed') return task.completed; if (filter === 'pending') return !task.completed; }); filteredTasks.forEach(task => { const li = document.createElement('li'); li.className = task.completed ? 'completed' : ''; li.innerHTML = ` <span>${task.text}</span> <div> <button class="complete-btn">${task.completed ? 'Undo' : 'Complete'}</button> <button class="delete-btn">Delete</button> </div> `; taskList.appendChild(li); li.querySelector('.complete-btn').addEventListener('click', () => { task.completed = !task.completed; saveTasks(); renderTasks(filter); }); li.querySelector('.delete-btn').addEventListener('click', () => { tasks = tasks.filter(t => t !== task); saveTasks(); renderTasks(filter); }); }); }; const saveTasks = () => { localStorage.setItem('tasks', JSON.stringify(tasks)); }; taskForm.addEventListener('submit', (e) => { e.preventDefault(); const newTask = { text: taskInput.value, completed: false }; tasks.push(newTask); saveTasks(); renderTasks(); taskInput.value = ''; }); filters.forEach(button => { button.addEventListener('click', () => { filters.forEach(btn => btn.classList.remove('active')); button.classList.add('active'); renderTasks(button.id); }); }); renderTasks(); });
- Explicación del Código
HTML
- Estructura Básica: El archivo
index.html
contiene la estructura básica de nuestra aplicación, incluyendo un formulario para añadir tareas, una lista para mostrar las tareas y botones para filtrar las tareas. - Formulario: El formulario tiene un campo de entrada para añadir nuevas tareas y un botón para enviar el formulario.
- Lista de Tareas: La lista de tareas (
<ul id="task-list">
) es donde se mostrarán las tareas. - Filtros: Los botones de filtro permiten al usuario ver todas las tareas, solo las completadas o solo las pendientes.
CSS
- Estilos Básicos: Los estilos en
styles.css
proporcionan una apariencia limpia y moderna a nuestra aplicación. - Estilos de Tareas: Las tareas completadas se muestran con un texto tachado y un color gris.
- Estilos de Filtros: Los botones de filtro tienen estilos para diferenciarse y cambiar de color al pasar el cursor sobre ellos.
JavaScript
- Carga Inicial: Al cargar la página, se obtienen las tareas almacenadas en
localStorage
y se renderizan. - Añadir Tareas: Al enviar el formulario, se añade una nueva tarea a la lista y se guarda en
localStorage
. - Completar/Eliminar Tareas: Cada tarea tiene botones para marcarla como completada o eliminarla. Estos botones actualizan el estado de las tareas y vuelven a renderizar la lista.
- Filtrar Tareas: Los botones de filtro permiten al usuario ver tareas según su estado (todas, completadas, pendientes).
- Ejercicios Prácticos
Ejercicio 1: Añadir una Funcionalidad de Edición de Tareas
Descripción: Añade la funcionalidad para editar el texto de una tarea existente.
Pistas:
- Añade un botón "Editar" junto a cada tarea.
- Al hacer clic en "Editar", convierte el texto de la tarea en un campo de entrada.
- Permite al usuario guardar los cambios y actualiza la tarea en
localStorage
.
Ejercicio 2: Añadir una Funcionalidad de Búsqueda de Tareas
Descripción: Añade una barra de búsqueda que permita al usuario buscar tareas por texto.
Pistas:
- Añade un campo de entrada de búsqueda en el HTML.
- Filtra las tareas en función del texto introducido en el campo de búsqueda.
- Actualiza la lista de tareas mostradas en tiempo real mientras el usuario escribe.
Conclusión
En esta sección, hemos construido una aplicación completa de gestión de tareas utilizando JavaScript, HTML y CSS. Este proyecto ha cubierto una amplia gama de conceptos y técnicas, desde la manipulación del DOM hasta el almacenamiento de datos en localStorage
. Los ejercicios adicionales proporcionan oportunidades para expandir y mejorar la funcionalidad de la aplicación, reforzando aún más tus habilidades en JavaScript. ¡Felicidades por llegar hasta aquí y buen trabajo!
JavaScript: De Principiante a Avanzado
Módulo 1: Introducción a JavaScript
- ¿Qué es JavaScript?
- Configuración de tu Entorno de Desarrollo
- Tu Primer Programa en JavaScript
- Sintaxis y Conceptos Básicos de JavaScript
- Variables y Tipos de Datos
- Operadores Básicos
Módulo 2: Estructuras de Control
- Sentencias Condicionales
- Bucles: for, while, do-while
- Sentencias Switch
- Manejo de Errores con try-catch
Módulo 3: Funciones
- Definición y Llamada de Funciones
- Expresiones de Función y Funciones Flecha
- Parámetros y Valores de Retorno
- Ámbito y Closures
- Funciones de Orden Superior
Módulo 4: Objetos y Arrays
- Introducción a los Objetos
- Métodos de Objeto y la Palabra Clave 'this'
- Arrays: Conceptos Básicos y Métodos
- Iteración sobre Arrays
- Desestructuración de Arrays
Módulo 5: Objetos y Funciones Avanzadas
- Prototipos y Herencia
- Clases y Programación Orientada a Objetos
- Módulos e Importación/Exportación
- JavaScript Asíncrono: Callbacks
- Promesas y Async/Await
Módulo 6: El Modelo de Objetos del Documento (DOM)
- Introducción al DOM
- Selección y Manipulación de Elementos del DOM
- Manejo de Eventos
- Creación y Eliminación de Elementos del DOM
- Manejo y Validación de Formularios
Módulo 7: APIs del Navegador y Temas Avanzados
- Almacenamiento Local y de Sesión
- Fetch API y AJAX
- WebSockets
- Service Workers y Aplicaciones Web Progresivas (PWAs)
- Introducción a WebAssembly
Módulo 8: Pruebas y Depuración
- Depuración de JavaScript
- Pruebas Unitarias con Jest
- Pruebas de Integración
- Pruebas de Extremo a Extremo con Cypress
Módulo 9: Rendimiento y Optimización
- Optimización del Rendimiento de JavaScript
- Gestión de Memoria
- Manipulación Eficiente del DOM
- Carga Perezosa y División de Código
Módulo 10: Frameworks y Librerías de JavaScript
- Introducción a React
- Gestión de Estado con Redux
- Conceptos Básicos de Vue.js
- Conceptos Básicos de Angular
- Elegir el Framework Adecuado