2
respostas

[Dúvida] por que tanto código?

Não sei se entendi direito, mas não poderia-mos ter feito tudo isso com um único innerHTML?

2 respostas

Boa pergunta, Luis! Olhando a função criarElementoTarefa do jeito que ela tá — com createElement, classList.add, append pra cada pedacinho — é natural pensar "eu fazia tudo isso com um innerHTML e pronto". E sabe o que? Dava sim. Olha como ficaria:

function criarElementoTarefa(tarefa) {
  const li = document.createElement('li')
  li.classList.add('app__section-task-list-item')
  li.innerHTML = `
    <svg class="app__section-task-icon-status" width="24" height="24" viewBox="0 0 24 24"
      fill="none" xmlns="http://www.w3.org/2000/svg">
      <circle cx="12" cy="12" r="12" fill="#FFF"></circle>
      <path d="M9 16.1719L19.5938 5.57812L21 6.98438L9 18.9844L3.42188 13.4062L4.82812 12L9 16.1719Z"
        fill="#01080E"></path>
    </svg>
    <p class="app__section-task-list-item-description">${tarefa.descricao}</p>
    <button class="app_button-edit">
      <img src="/imagens/edit.png">
    </button>
  `
  return li
}

Menos código, mais fácil de ler. E nesse momento do curso, onde a gente só cria e exibe tarefas, funcionaria perfeitamente. Então por que a gente não fez assim?

Porque essa função vai crescer. No decorrer do curso, a gente vai precisar adicionar comportamento nesses elementos — um clique no botão de editar, um clique no item pra selecionar a tarefa ativa, marcar como concluída. E quando você constrói tudo com innerHTML, os elementos até existem no DOM, mas você não tem uma referência direta a eles no JavaScript. Pra adicionar um addEventListener no botão de editar, por exemplo, você precisaria buscar o elemento depois de montar o HTML:

function criarElementoTarefa(tarefa) {
  const li = document.createElement('li')
  li.classList.add('app__section-task-list-item')
  li.innerHTML = `...todo o HTML aqui...`

  // agora precisa ir buscar o botão que acabou de criar
  const botao = li.querySelector('.app_button-edit')
  botao.addEventListener('click', () => {
    // lógica de edição
  })

  return li
}

Funciona? Funciona. Mas percebe o que aconteceu? Você montou tudo como string e logo em seguida precisou ir atrás do elemento pra manipular ele como objeto. Criou como texto, mas precisou dele como nó do DOM. É meio que fazer o caminho de ida e volta sem necessidade.

Com createElement, você já tem a referência do botão na mão desde o momento em que ele nasce:

const botao = document.createElement('button')
botao.classList.add('app_button-edit')
botao.addEventListener('click', () => {
  // lógica de edição
})
li.append(botao)

Não precisa buscar nada. O botao já é o objeto, já tá ali, pronto pra receber evento, classe, atributo — o que você precisar.

E tem um outro ponto que é mais sutil, mas importa: segurança. Repara que na versão com innerHTML a gente faz ${tarefa.descricao} direto dentro da string de HTML. Se por algum motivo essa descrição vier com algo tipo <img src=x onerror="alert('hackeado')">, o browser vai executar esse script. Isso se chama XSS (Cross-Site Scripting) e é uma vulnerabilidade real. Quando a gente usa paragrafo.textContent = tarefa.descricao, o browser trata aquilo como texto puro — não interpreta nenhuma tag HTML. É mais seguro por padrão.

Agora, isso tudo não quer dizer que innerHTML é proibido. Ele funciona super bem pra montar blocos de conteúdo estático, onde você não vai precisar manipular os elementos filhos individualmente. Mas na criarElementoTarefa, onde cada pedaço do item vai ganhar comportamento ao longo do curso, o createElement dá pra gente o controle que a gente precisa desde o início.

E tem o lado pedagógico também, que pra mim é o mais importante: o curso tá te ensinando a entender o DOM como uma árvore de objetos. Cada nó tem propriedades, métodos, relações de pai e filho. Quando você usa createElement, você tá trabalhando diretamente com essa estrutura. E esse entendimento é o que vai te fazer olhar pra um framework como React lá na frente e pensar "ah, eu sei o que tá acontecendo por baixo dos panos". Porque no fundo, é a mesma ideia — criar nós, configurar, encaixar na árvore.

Então a versão curta da resposta: dava pra usar innerHTML? Dava. Mas aí a gente teria aprendido a montar string de HTML, não a manipular o DOM. E é o DOM que vai te acompanhar daqui pra frente.

Agradeço a explicação! muito boa e aprofundada. Da melhor forma possível!