Atividade DOM — Painel TaskFlow
Disciplina: Programação Web 2
Assunto: DOM — Document Object Model
Professor: Me. Danilo Bueno
Grupos: duplas
Duração: 4 aulas de 50 minutos (em sala)
Importante
Antes de começar a atividade leia o material de apoio sobre DOM. É imprescindível que você leia antes de codar, pois a atividade é justamente para praticar os conceitos apresentados no material. Se tiver dúvidas, releia o material, pergunte ao professor ou aos colegas. Você também pode consultar os slides da aula.
Contextualização
A TaskFlow é uma startup de gestão de tarefas para times de tecnologia. O time de backend já entregou os dados: um array JavaScript com as tarefas do sprint atual.
O problema é que nada aparece na tela — o frontend ainda não existe. Os dados estão lá, mas sem DOM nenhuma tarefa é exibida ao usuário.
Você e sua dupla foram contratados como o time de frontend para construir a interface.
Como começar
Crie dois arquivos na mesma pasta, nomeados exatamente assim (sem nomes):
index.html — cole o conteúdo abaixo:
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<title>TaskFlow</title>
</head>
<body>
<h1>TaskFlow</h1>
<ul id="lista-tarefas"></ul>
<script src="tarefas.js"></script>
</body>
</html>
tarefas.js — cole o conteúdo abaixo:
// Como executar:
// abra o index.html no navegador (duplo clique ou arraste para o Chrome)
// pressione F12 para ver erros no Console
// ─────────────────────────────────────────────────────────────
const tarefas = [
{ id: 1, titulo: "Criar wireframe da homepage", responsavel: "Ana", concluida: false },
{ id: 2, titulo: "Implementar login com JWT", responsavel: "Carlos", concluida: true },
{ id: 3, titulo: "Revisar pull request #42", responsavel: "Ana", concluida: false },
{ id: 4, titulo: "Configurar CI/CD no GitHub Actions", responsavel: "Bruno", concluida: false },
{ id: 5, titulo: "Escrever testes unitários", responsavel: "Carlos", concluida: true },
];
Todo o JavaScript da atividade vai no tarefas.js, logo abaixo do array. Recarregue o navegador (F5) para ver cada mudança.
Se o HTML abrir mas nada acontecer, abra o DevTools (F12 → aba Console) — os erros aparecem lá com o número da linha.
Como funciona
O arquivo tarefas.js tem 4 missões. Implemente cada tarefa logo abaixo do array tarefas.
Dica: a cada tarefa concluída, recarregue o navegador e confira o resultado antes de avançar.
Cronograma
| Aula | Foco | Missões |
|---|---|---|
| 1ª | Setup + renderização | Missão 1 |
| 2ª | Eventos de clique | Missão 2 |
| 3ª | Formulário | Missão 3 |
| 4ª | Remoção + entrega | Missão 4 + envio |
Material de apoio
- MDN — querySelector
- MDN — createElement
- MDN — addEventListener
- MDN — classList
- MDN — event.target
- MDN — event.preventDefault
Missão 1 — Renderizando as Tarefas
Objetivo: exibir todas as tarefas do array como itens <li> na lista do HTML.
Tarefa 1.1: selecione o elemento <ul id="lista-tarefas"> com querySelector e guarde na constante lista.
Tarefa 1.2: percorra o array tarefas com for...of. Para cada tarefa, crie um elemento <li> com createElement, defina seu textContent com o título e o responsável no formato abaixo, e adicione o <li> à lista com appendChild.
Criar wireframe da homepage — Ana
Implementar login com JWT — Carlos
Revisar pull request #42 — Ana
...
Tarefa 1.3: tarefas que já estão concluídas (concluida: true) devem aparecer visualmente diferentes. Após criar o <li>, verifique se tarefa.concluida é true e adicione a classe "concluida" com classList.add.
No index.html, adicione o estilo abaixo dentro de um <style> na <head>:
<style>
.concluida { text-decoration: line-through; opacity: 0.5; }
</style>
Pergunta: por que usar
textContente nãoinnerHTMLpara definir o título da tarefa?
Missão 2 — Marcando como Concluída
Objetivo: ao clicar numa tarefa, alternar visualmente entre concluída e pendente.
Tarefa 2.1: ainda dentro do for...of da Missão 1, adicione um addEventListener de "click" em cada <li>. Dentro do callback, use classList.toggle("concluida") no próprio <li>.
Tarefa 2.2: abra o navegador e clique nas tarefas. O clique deve alternar o estilo riscado. Clique duas vezes seguidas na mesma tarefa — ela deve voltar ao estado original.
Pergunta: o que o
togglefaz que seria trabalhoso implementar manualmente comadderemove?
Missão 3 — Adicionando Novas Tarefas
Objetivo: permitir que o usuário adicione tarefas pelo formulário.
Tarefa 3.1: no index.html, adicione um formulário abaixo do <ul>:
<form id="form-nova-tarefa">
<input type="text" id="campo-titulo" placeholder="Título da tarefa" />
<input type="text" id="campo-responsavel" placeholder="Responsável" />
<button type="submit">Adicionar</button>
</form>
Tarefa 3.2: no tarefas.js, selecione o <form> com querySelector e adicione um listener do evento "submit". Dentro do callback:
- Chame
event.preventDefault()para evitar o recarregamento da página. - Leia os valores dos dois inputs com
.value.trim(). - Se qualquer campo estiver vazio, exiba
alert("Preencha todos os campos.")e retorne cedo (return).
Pergunta: o que acontece se você não chamar
event.preventDefault()no submit do formulário?
Tarefa 3.3: ainda dentro do callback, crie um <li> com createElement, defina o textContent com título e responsável (mesmo formato da Missão 1) e insira na lista com appendChild.
Tarefa 3.4: após inserir a tarefa, limpe os dois campos (input.value = "") e devolva o foco ao primeiro campo (inputTitulo.focus()).
Missão 4 — Removendo Tarefas e Contando Pendentes
Objetivo: adicionar um botão “Remover” em cada tarefa e exibir o total de tarefas pendentes.
Tarefa 4.1: modifique a criação do <li> (feita nas Missões 1 e 3) para incluir um <button> com o texto "✕" dentro de cada item. Use createElement, defina textContent e insira o botão no <li> com appendChild antes de adicionar o <li> à lista.
Tarefa 4.2: adicione um listener de "click" no botão. No callback, remova o <li> pai com:
botao.parentElement.remove();
Atenção: o listener de
"click"do botão e o do<li>(toggle de concluída) vão conflitar — clicar no botão também dispara o clique no<li>. Resolva isso chamandoevent.stopPropagation()dentro do listener do botão, antes de remover o item.
Tarefa 4.3: no index.html, adicione um parágrafo para o contador, logo acima do <ul>:
<p id="contador">Tarefas pendentes: 0</p>
Crie uma função chamada atualizarContador() que:
- Conta quantos
<li>na lista não têm a classe"concluida"(dica: subtraia o total dos<li>pelo número dequerySelectorAll(".concluida")). - Atualiza o
textContentdo<p id="contador">.
Chame atualizarContador() após cada mudança: ao renderizar a lista inicial, ao clicar (toggle), ao adicionar nova tarefa e ao remover.
Tarefa 4.4 (desafio): o botão “Remover” acima não sincroniza com o array JavaScript. Implemente a remoção também no array: ao clicar em ”✕”, além de remover o <li>, encontre o objeto correspondente no array tarefas e remova com splice.
Para isso, no momento da criação do <li>, guarde o id da tarefa num atributo data-id:
li.dataset.id = tarefa.id;
Ao remover, use findIndex para localizar o item e splice para remover.
Entrega individual (cada integrante deve enviar seu próprio arquivo)
- Responder o questionário (link no Moodle)
- Enviar o arquivo
tarefas.jscom as missões completas