Proyecto: una lista de tareas con JavaScript
Una to-do list de verdad: añadir, marcar como hecha, borrar y guardar en el navegador con localStorage. El código funciona aquí mismo.
Qué vas a construir
Una lista de tareas que se guarda en tu navegador: escribes una tarea, la marcas al terminarla y sigue ahí aunque cierres la pestaña. Junta el DOM, los eventos, un array de objetos y localStorage.
Esto no es una simulación: es el JavaScript real de la página, funcionando. Añade tareas y recarga la página para ver que se guardan.
Paso 1: el HTML mínimo
Un formulario para escribir, una lista vacía y un sitio para el contador. Nada más.
<form id="todoForm">
<input type="text" id="todoInput" placeholder="Nueva tarea…">
<button type="submit">Añadir</button>
</form>
<ul id="todoList"></ul>
<p id="todoCount"></p>
Paso 2: guardar las tareas en un array
Cada tarea es un objeto { texto, hecha }. Todas juntas, un array. El array es la "verdad": la pantalla solo lo dibuja.
let tareas = [];
document.getElementById("todoForm").addEventListener("submit", (e) => {
e.preventDefault(); // no recargar la página
const input = document.getElementById("todoInput");
const texto = input.value.trim();
if (!texto) return;
tareas.push({ texto: texto, hecha: false });
input.value = "";
render();
});
Paso 3: dibujar la lista (render)
Borramos la lista y la volvemos a construir desde el array. Cada tarea genera un <li> con su checkbox y su botón de borrar.
function render() {
const ul = document.getElementById("todoList");
ul.innerHTML = "";
tareas.forEach((t, i) => {
const li = document.createElement("li");
if (t.hecha) li.classList.add("is-done");
const chk = document.createElement("input");
chk.type = "checkbox";
chk.checked = t.hecha;
chk.addEventListener("change", () => {
tareas[i].hecha = chk.checked;
render();
});
const span = document.createElement("span");
span.textContent = t.texto;
const del = document.createElement("button");
del.textContent = "✕";
del.addEventListener("click", () => {
tareas.splice(i, 1);
render();
});
li.append(chk, span, del);
ul.appendChild(li);
});
const pendientes = tareas.filter(t => !t.hecha).length;
document.getElementById("todoCount").textContent = "Quedan " + pendientes;
}
textContent y no innerHTML para el texto de la tarea: así, si alguien escribe <script>, se ve como texto y no se ejecuta.Paso 4: que no se pierda (localStorage)
localStorage solo guarda texto, así que convertimos el array a JSON al guardar y de vuelta al cargar.
function guardar() {
localStorage.setItem("tareas", JSON.stringify(tareas));
}
// al arrancar la página:
tareas = JSON.parse(localStorage.getItem("tareas")) || [];
render();
// y llamamos a guardar() después de cada cambio (añadir, marcar, borrar)
Cómo seguir
- Editar una tarea con doble clic.
- Filtros: todas / pendientes / hechas.
- Arrastrar para reordenar.
- Cambiar
localStoragepor una API real con fetch.