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;
}

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 localStorage por una API real con fetch.