Pular para o conteúdo
murad.guide

As Três Camadas

Capítulo 16

Exercício: quiz

4 min de leitura 689 palavras 1 gravura

Hora de juntar variáveis, decisões e funções numa página. Você monta um quiz da Oficina do Farol: perguntas em uma lista, botões verdadeiro e falso, placar na tela. Tudo mora na pasta exemplos/16-quiz/. Não use editor online.

Array é uma lista numerada. O primeiro item fica no índice 0. Cada item da nossa lista é uma pergunta com texto e resposta.

Trabalhe na cópia inicio desta etapa. Leia e digite o código indicado; mude apenas uma coisa. Antes de recarregar, escreva o resultado que espera. Depois compare com a referência completa ao lado. Se algo falhar, confira primeiro o arquivo salvo e o caminho aberto.

O que você vai aprender

A página local do quiz

Três arquivos bastam: index.html, styles.css e quiz.js. Abra o HTML no disco ou em 127.0.0.1. O script fica no fim do body.

<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Quiz da oficina — Oficina do Farol</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <main>
    <h1>Quiz da Oficina do Farol</h1>
    <p id="pergunta">Carregando…</p>
    <p>
      <button type="button" id="verdadeiro">Verdadeiro</button>
      <button type="button" id="falso">Falso</button>
    </p>
    <p id="placar">Acertos: 0 de 0</p>
  </main>
  <script src="quiz.js"></script>
</body>
</html>

id marca os pedaços que o JavaScript vai trocar. Os botões não enviam formulário.

Pare e experimente. Abra o exemplo e leia a primeira pergunta. Preveja um texto da oficina, não a palavra “Carregando”. Recarregue se o script não ligou.

Erro comum: salvar quiz.js com outro nome e deixar src="quiz.js". A pergunta fica em “Carregando…”.

A lista de perguntas

No topo de quiz.js, declare as perguntas. Cada objeto tem texto e resposta. true é verdadeiro. false é falso.

const perguntas = [
  {
    texto: "A Oficina do Farol fica em Olinda.",
    resposta: true
  },
  {
    texto: "O operador = compara dois valores.",
    resposta: false
  },
  {
    texto: "No JavaScript deste curso, contamos índices a partir de 0.",
    resposta: true
  }
];

Três itens bastam para o primeiro jogo. Depois você acrescenta mais, sempre com vírgula entre eles e sem vírgula depois do último se preferir o estilo do exemplo.

Dois let acompanham a lista: o índice da pergunta da vez e o placar.

let indice = 0;
let acertos = 0;

Pare e experimente. Inverta a resposta da segunda pergunta para true. Preveja um ponto a mais se você clicar em Verdadeiro. Restaure false depois do teste.

Erro comum: escrever a resposta como texto "true". A comparação com o boolean do botão falha.

Mostrar, ouvir e somar

Duas funções resolvem o jogo. Uma desenha a pergunta. A outra recebe o palpite.

const elPergunta = document.getElementById("pergunta");
const elPlacar = document.getElementById("placar");

function mostrarPergunta() {
  elPlacar.textContent = `Acertos: ${acertos} de ${perguntas.length}`;
  if (indice >= perguntas.length) {
    elPergunta.textContent = "Fim do quiz da oficina.";
    return;
  }
  elPergunta.textContent = perguntas[indice].texto;
}

function responder(palpite) {
  if (indice >= perguntas.length) {
    return;
  }
  if (palpite === perguntas[indice].resposta) {
    acertos += 1;
  }
  indice += 1;
  mostrarPergunta();
}

document.getElementById("verdadeiro").addEventListener("click", function () {
  responder(true);
});
document.getElementById("falso").addEventListener("click", function () {
  responder(false);
});

mostrarPergunta();

perguntas.length é o tamanho da lista. Quando indice chega lá, o quiz termina.

addEventListener espera o clique. Você ainda vai estudar o DOM com calma no capítulo 19. Aqui o bloco já vem pronto no exemplo: copie, leia e mude uma pergunta.

O placar usa template string. A cada resposta certa, acertos += 1.

Pare e experimente. Responda as três. Preveja o texto de fim e o número de acertos. Recarregue para jogar de novo.

Erro comum: esquecer mostrarPergunta() no fim do arquivo. Os botões existem, mas a primeira frase não aparece.

O jogo fica na pasta

O CSS do exemplo só organiza título, botões e placar. Cores da oficina: texto escuro, botão terracota #c45c26 no verdadeiro, cinza no falso.

Não publique respostas de pessoas reais. As perguntas falam da oficina fictícia e do que você estudou.

Não leve o exercício para um editor na nuvem. Se o arquivo abre em exemplos/16-quiz/, o volume está no caminho certo.

Quiz local com pergunta, botões verdadeiro e falso e placar

Compare o diagrama com a sua tela. O placar deve subir só no acerto.

Atividades

  1. Em que índice está a primeira pergunta do array?
  2. O que palpite === perguntas[indice].resposta decide?
  3. Como o jogador vê o placar depois da última pergunta?
  4. Por que o quiz deste volume não depende de um site de rascunho na internet?

Respostas comentadas

  1. No índice 0. perguntas[0].texto é a frase sobre Olinda.
  2. Se o botão clicado bate com a resposta guardada, soma um acerto.
  3. mostrarPergunta troca o texto para “Fim do quiz da oficina.” e o #placar já mostra Acertos: X de 3.
  4. Os três arquivos na pasta 16-quiz já abrem no navegador. O exercício não precisa de conta nem de página alheia.

Referências

O arquivo completo

Referência do exemplo 16-quiz, reproduzida aqui para que você possa conferir sem sair da página.

index.html

<!DOCTYPE html>

<html lang="pt-BR">
<head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<title>Quiz</title>
<link href="styles.css" rel="stylesheet"/>
<style>body{overflow-wrap:anywhere}img,input,textarea,select,iframe{max-width:100%}img{height:auto}fieldset,.cartao{min-width:0}pre{max-width:100%;overflow:auto}:focus-visible{outline:3px solid #005fcc;outline-offset:3px}.atalho-conteudo{position:absolute;left:.5rem;top:-6rem;background:white;color:#172f50;padding:.5rem;z-index:999}.atalho-conteudo:focus{top:.5rem}@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}</style></head>
<body><a class="atalho-conteudo" href="#conteudo">Pular para o conteúdo</a><main id="conteudo" tabindex="-1">
<h1>Quiz da Oficina</h1>
<p id="pergunta"></p>
<p>
<button id="verdadeiro" type="button">Verdadeiro</button>
<button id="falso" type="button">Falso</button>
</p>
<p aria-live="polite" id="placar"></p>

</main><script src="quiz.js"></script></body>
</html>

lab.css

body { font-family: "Segoe UI", Tahoma, sans-serif; background: #fffaf3; color: #1c1917; margin: 0; padding: 1.2rem; max-width: 48rem; }
code, pre { font-family: Consolas, ui-monospace, monospace; }
pre { background: #111; color: #f4ead8; padding: 1rem; overflow: auto; }
.ok { color: #1b5e20; }
.fail { color: #b71c1c; }
button { font: inherit; padding: 0.4rem 0.8rem; }
button:focus, select:focus, input:focus { outline: 3px solid #c45c26; }