Skip to content
← 1001 Widgets
N° 012 · ●○○

Quiz

A multiple-choice quiz on web basics, with the right answer revealed and a score at the end. The right exercise to chain screens without changing page.

HTMLJS
What you'll learn
  • Store the questions in an array
  • Show the next screen from the state
  • Reveal the right answer after a choice
Why this language

Pourquoi un quiz ? Questions, réponses, score : c'est le format le plus simple pour apprendre à séparer le contenu du code. Les questions vivent dans un tableau, le code ne fait que les dérouler.

Changer de sujet, c'est changer le tableau, sans toucher à une seule ligne de logique.

Pourquoi en JavaScript simple ? Un numéro de question, un score, une fonction d'affichage.

How it works
  1. LES QUESTIONS

    Le contenu est séparé du code : pour un autre quiz, on ne change que ce tableau.

    const QUESTIONS = [
      { q: 'Quelle balise pour le titre principal ?', choix: ['<title>', '<h1>', '<header>'], bonne: 1 },
      { q: 'Que renvoie typeof null ?', choix: ['"null"', '"undefined"', '"object"'], bonne: 2 },
      { q: 'Quelle unité suit la taille de police de la page ?', choix: ['rem', 'px', 'vh'], bonne: 0 }
    ];
  2. LE HTML

    <p id="question"></p>
    <div id="choix"></div>
    <p id="retour" aria-live="polite"></p>
  3. L'ÉTAT

    let index = 0;
    let score = 0;
  4. AFFICHER UNE QUESTION

    textContent affiche « <h1> » tel quel, sans créer de balise.

    function afficher() {
      const { q, choix } = QUESTIONS[index];
      document.getElementById('question').textContent = q;
      const zone = document.getElementById('choix');
      zone.innerHTML = '';
      choix.forEach((c, i) => {
        const b = document.createElement('button');
        b.textContent = c;
        b.dataset.i = i;
        zone.append(b);
      });
    }
  5. RÉPONDRE

    On compare des numéros, jamais des textes.

    document.getElementById('choix').addEventListener('click', e => {
      if (e.target.dataset.i === undefined) return;
      const juste = Number(e.target.dataset.i) === QUESTIONS[index].bonne;
      if (juste) score++;
      document.getElementById('retour').textContent = juste ? 'Bonne réponse.' : 'Raté.';
      index++;
      if (index < QUESTIONS.length) {
        afficher();
      } else {
        document.getElementById('question').textContent = `Score : ${score} / ${QUESTIONS.length}`;
        document.getElementById('choix').innerHTML = '';
      }
    });
    afficher();
Pitfalls

PIÈGE 1 : Comparer les textes

Pitfall

Mauvais : comparer le texte cliqué au texte de la bonne réponse. Une espace en trop, et la bonne réponse est comptée fausse.

Fix

Correct : comparer des numéros, comme dataset.i et bonne.

PIÈGE 2 : Les balises qui disparaissent

Pitfall

Mauvais : b.innerHTML = '<h1>'. Le navigateur crée une vraie balise, et le bouton reste vide.

Fix

Correct : textContent affiche le texte tel quel.

PIÈGE 3 : Passer trop vite

Pitfall

Mauvais : enchaîner sur la question suivante au même instant. On n'a pas le temps de voir si on avait juste.

Fix

Correct : montrer la bonne réponse, puis passer à la suite au clic sur « Suivant » (c'est ce que fait la démo).

PERSONNALISER
  • Mélanger les questions et les réponses à chaque partie, avec le mélange de Fisher-Yates.
  • Une explication par question, affichée après la réponse.
  • Vos questions : remplacez le tableau, ou chargez-le depuis un fichier JSON.
OPTIMISATION
  • Gardez le meilleur score dans localStorage pour donner envie de rejouer.
  • Un temps limite par question : c'est la variante « Quiz chronométré ».
VERS REACT

index et score dans un useState, et les questions en prop : le même composant sert pour n'importe quel quiz.

La phase (question, correction, fin) dans un seul état, plutôt que trois booléens.

Variants
Comments
0/1000

Loading comments…

Audience measurement

With your consent, this site measures its traffic with Google Analytics and the Meta pixel, via Google Tag Manager. Nothing is loaded until you choose, and you can change your mind at any time with the "Cookies" link at the bottom of the page.