Projeto 2: Lista de Tarefas (To-Do List) Básica

Desenvolva uma aplicação simples para adicionar e remover itens de uma lista.

Uma lista de tarefas é um dos projetos mais clássicos para aprender JavaScript, porque ela combina várias habilidades importantes em um único fluxo: capturar texto digitado, guardar dados em memória, mostrar itens na tela e reagir a cliques para remover tarefas.

Pense nesse projeto como uma “mesa de organização”:

  • o usuário escreve uma tarefa (entrada),
  • o sistema guarda essa tarefa (estado),
  • e mostra tudo em uma lista visual (interface).

O que este projeto reforça da sua base

Neste projeto, você pratica conceitos essenciais de JavaScript que já estudou:

  • Variáveis e arrays para guardar tarefas.
  • Objetos para representar cada tarefa (ex.: id, texto, concluída).
  • Eventos (submit, click) para reagir às ações do usuário.
  • DOM para criar, atualizar e remover elementos da página.
  • Funções para separar responsabilidades (adicionar, renderizar, remover).
  • Condição para validar entrada vazia.
  • Boas práticas para manter o código legível e fácil de evoluir.

Estratégia simples de construção

Uma forma organizada de montar sua To-Do List:

  1. Criar um formulário com input e botão de adicionar.
  2. Criar um array tarefas para armazenar os dados.
  3. No envio do formulário, impedir recarregamento com preventDefault().
  4. Validar o texto digitado.
  5. Adicionar a nova tarefa no array.
  6. Atualizar a lista na tela com uma função renderizarTarefas().
  7. Permitir remover tarefas com clique em botão de excluir.

Exemplo completo (HTML + CSS + JS em um único arquivo)

<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>To-Do List Básica</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      background: #f5f7fb;
      margin: 0;
      min-height: 100vh;
      display: grid;
      place-items: center;
    }

    .app {
      width: 100%;
      max-width: 420px;
      background: #fff;
      border-radius: 12px;
      box-shadow: 0 10px 25px rgba(0,0,0,0.08);
      padding: 20px;
    }

    h1 {
      margin-top: 0;
      font-size: 1.4rem;
      color: #222;
      text-align: center;
    }

    form {
      display: flex;
      gap: 8px;
      margin-bottom: 16px;
    }

    input {
      flex: 1;
      padding: 10px;
      border: 1px solid #cfd6e4;
      border-radius: 8px;
      font-size: 0.95rem;
    }

    button {
      border: none;
      border-radius: 8px;
      padding: 10px 14px;
      cursor: pointer;
      font-size: 0.95rem;
    }

    .btn-add {
      background: #2563eb;
      color: #fff;
    }

    ul {
      list-style: none;
      padding: 0;
      margin: 0;
    }

    li {
      display: flex;
      justify-content: space-between;
      align-items: center;
      background: #f1f5f9;
      margin-bottom: 8px;
      padding: 10px 12px;
      border-radius: 8px;
      gap: 10px;
    }

    .texto-tarefa {
      word-break: break-word;
    }

    .btn-remove {
      background: #ef4444;
      color: #fff;
      flex-shrink: 0;
    }

    .vazio {
      color: #64748b;
      text-align: center;
      font-size: 0.95rem;
      margin-top: 10px;
    }
  </style>
</head>
<body>
  <main class="app">
    <h1>Minha To-Do List</h1>

    <form id="form-tarefa">
      <input id="input-tarefa" type="text" placeholder="Digite uma tarefa..." />
      <button class="btn-add" type="submit">Adicionar</button>
    </form>

    <ul id="lista-tarefas"></ul>
    <p id="mensagem-vazia" class="vazio">Nenhuma tarefa por enquanto.</p>
  </main>

  <script>
    const form = document.getElementById("form-tarefa");
    const input = document.getElementById("input-tarefa");
    const lista = document.getElementById("lista-tarefas");
    const mensagemVazia = document.getElementById("mensagem-vazia");

    let tarefas = [];

    function renderizarTarefas() {
      lista.innerHTML = "";

      if (tarefas.length === 0) {
        mensagemVazia.style.display = "block";
        return;
      }

      mensagemVazia.style.display = "none";

      tarefas.forEach((tarefa) => {
        const item = document.createElement("li");

        const span = document.createElement("span");
        span.className = "texto-tarefa";
        span.textContent = tarefa.texto;

        const botaoRemover = document.createElement("button");
        botaoRemover.className = "btn-remove";
        botaoRemover.textContent = "Remover";
        botaoRemover.addEventListener("click", () => {
          removerTarefa(tarefa.id);
        });

        item.appendChild(span);
        item.appendChild(botaoRemover);
        lista.appendChild(item);
      });
    }

    function adicionarTarefa(texto) {
      const novaTarefa = {
        id: Date.now(),
        texto: texto
      };

      tarefas.push(novaTarefa);
      renderizarTarefas();
    }

    function removerTarefa(id) {
      tarefas = tarefas.filter((tarefa) => tarefa.id !== id);
      renderizarTarefas();
    }

    form.addEventListener("submit", (event) => {
      event.preventDefault();

      const textoDigitado = input.value.trim();

      if (textoDigitado === "") {
        alert("Digite uma tarefa antes de adicionar.");
        return;
      }

      adicionarTarefa(textoDigitado);
      input.value = "";
      input.focus();
    });

    renderizarTarefas();
  </script>
</body>
</html>

Entendendo a lógica principal

  • O array tarefas é a “fonte da verdade” do sistema.
  • A função renderizarTarefas() desenha a interface com base no array atual.
  • A função adicionarTarefa() insere um novo item no array.
  • A função removerTarefa() usa filter() para gerar um novo array sem a tarefa removida.
  • O evento submit captura a ação do formulário e preventDefault() impede o recarregamento da página.

Melhorias para evoluir o projeto

Depois da versão básica, você pode implementar:

  • Marcar tarefa como concluída.
  • Contador de tarefas pendentes e concluídas.
  • Filtro por status (todas, pendentes, concluídas).
  • Persistência com localStorage.
  • Edição de tarefa já criada.
  • Delegação de eventos para listas maiores.