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.htmlcontiene 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.cssproporcionan 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
localStoragey 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
