Leçon 12 / 12
Leçon 12 · Partie 3 — JavaScript & le Web

Mini-projet : quiz interactif

Ce qu'on va construire

On assemble tout ce qu'on a appris pour créer un quiz interactif. L'utilisateur répond à des questions, voit si c'est correct, et obtient son score.

Ce projet combine :

  • Un tableau d'objets pour les questions
  • Des fonctions pour organiser le code
  • Le DOM pour afficher les questions
  • Les événements pour détecter les clics
  • Les conditions pour vérifier les réponses

La structure HTML

index.html
<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <title>Quiz JavaScript</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

  <div id="quiz">
    <div id="progression">Question <span id="numQuestion">1</span> / <span id="totalQuestions"></span></div>
    <h2 id="question"></h2>
    <div id="reponses"></div>
    <p id="feedback"></p>
    <button id="btnSuivant" style="display:none">Question suivante →</button>
  </div>

  <div id="resultat" style="display:none">
    <h2>Quiz terminé !</h2>
    <p id="score"></p>
    <button id="btnRecommencer">Recommencer</button>
  </div>

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

Le JavaScript complet — quiz.js

quiz.js
// ===== LES QUESTIONS DU QUIZ =====
const questions = [
  {
    texte: "Quel mot-clé utilise-t-on pour déclarer une variable qui ne changera pas ?",
    reponses: ["var", "let", "const", "fixed"],
    bonne: 2 // index 2 → "const"
  },
  {
    texte: "Que retourne : typeof \"Bonjour\" ?",
    reponses: ["\"text\"", "\"string\"", "\"char\"", "\"word\""],
    bonne: 1
  },
  {
    texte: "Comment ajoute-t-on un élément à la fin d'un tableau ?",
    reponses: ["tableau.add()", "tableau.append()", "tableau.push()", "tableau.insert()"],
    bonne: 2
  },
  {
    texte: "Quel opérateur compare la valeur ET le type ?",
    reponses: ["==", "===", "!=", "!=="],
    bonne: 1
  },
  {
    texte: "Comment sélectionner un élément HTML par son id ?",
    reponses: [
      "document.getElement(\"id\")",
      "document.querySelector(\".monId\")",
      "document.getElementById(\"monId\")",
      "document.select(\"#monId\")"
    ],
    bonne: 2
  }
];

// ===== VARIABLES D'ÉTAT =====
let indexQuestion = 0; // question actuelle
let score = 0;          // nombre de bonnes réponses
let aRepondu = false;  // a-t-on déjà répondu à cette question ?

// ===== RÉCUPÉRATION DES ÉLÉMENTS DOM =====
const divQuiz       = document.getElementById("quiz");
const divResultat   = document.getElementById("resultat");
const elmNumQ       = document.getElementById("numQuestion");
const elmTotal      = document.getElementById("totalQuestions");
const elmQuestion   = document.getElementById("question");
const divReponses   = document.getElementById("reponses");
const elmFeedback   = document.getElementById("feedback");
const btnSuivant    = document.getElementById("btnSuivant");
const elmScore      = document.getElementById("score");
const btnRecommencer= document.getElementById("btnRecommencer");

// ===== FONCTIONS =====

// Affiche la question actuelle
function afficherQuestion() {
  const q = questions[indexQuestion];

  // Mise à jour de la progression
  elmNumQ.textContent  = indexQuestion + 1;
  elmTotal.textContent = questions.length;

  // Affiche la question
  elmQuestion.textContent = q.texte;

  // Crée les boutons de réponse
  divReponses.innerHTML = ""; // efface les réponses précédentes
  q.reponses.forEach(function(reponse, index) {
    const btn = document.createElement("button");
    btn.textContent = reponse;
    btn.className    = "btn-reponse";
    btn.addEventListener("click", () => verifierReponse(index));
    divReponses.appendChild(btn);
  });

  // Réinitialise l'état
  elmFeedback.textContent = "";
  btnSuivant.style.display  = "none";
  aRepondu = false;
}

// Vérifie si la réponse choisie est correcte
function verifierReponse(indexChoisi) {
  if (aRepondu) return; // on ne peut répondre qu'une fois

  aRepondu = true;
  const q = questions[indexQuestion];
  const boutons = divReponses.querySelectorAll(".btn-reponse");

  // Colore tous les boutons (vert = bonne réponse, rouge = mauvaise)
  boutons.forEach((btn, i) => {
    if (i === q.bonne) {
      btn.classList.add("correct");
    } else if (i === indexChoisi) {
      btn.classList.add("incorrect");
    }
    btn.disabled = true; // désactive tous les boutons
  });

  // Message de feedback
  if (indexChoisi === q.bonne) {
    score++;
    elmFeedback.textContent = "✅ Bonne réponse !";
  } else {
    elmFeedback.textContent = `❌ Mauvaise réponse. La bonne réponse était : "${q.reponses[q.bonne]}"`;
  }

  // Afficher le bouton "Suivant"
  btnSuivant.style.display = "inline-block";
}

// Passe à la question suivante ou affiche le résultat
function questionSuivante() {
  indexQuestion++;

  if (indexQuestion < questions.length) {
    afficherQuestion();
  } else {
    afficherResultat();
  }
}

// Affiche le score final
function afficherResultat() {
  divQuiz.style.display    = "none";
  divResultat.style.display = "block";

  const pct = Math.round(score / questions.length * 100);
  let mention;

  if (pct >= 80) mention = "🏆 Excellent !";
  else if (pct >= 60) mention = "👍 Bien joué !";
  else mention = "📚 Continue à pratiquer !";

  elmScore.innerHTML = `
    Tu as obtenu <strong>${score}/${questions.length}</strong> (${pct}%)
${mention} `
; } // ===== ÉVÉNEMENTS ===== btnSuivant.addEventListener("click", questionSuivante); btnRecommencer.addEventListener("click", function() { indexQuestion = 0; score = 0; divQuiz.style.display = "block"; divResultat.style.display = "none"; afficherQuestion(); }); // ===== DÉMARRAGE ===== afficherQuestion();

Points clés à retenir de ce projet

Ce quiz utilise tout ce qu'on a vu :

  • Un tableau d'objets pour les questions
  • Des variables d'état (indexQuestion, score, aRepondu) pour suivre la progression
  • Des fonctions séparées : une pour afficher, une pour vérifier, une pour passer à la suivante
  • forEach pour créer les boutons
  • addEventListener sur chaque bouton
  • classList.add pour colorer les réponses en vert/rouge
  • DOM pour afficher ou cacher des sections
🚀

Pour aller plus loin : améliore ce quiz ! Idées : ajouter une barre de progression, mélanger les questions avec sort(() => Math.random() - 0.5), sauvegarder le meilleur score dans localStorage, ajouter un timer…

// Félicitations !
  • Tu maîtrises les bases de JavaScript
  • Variables, types, opérateurs, conditions, boucles, fonctions : tu sais les utiliser
  • Tu peux accéder au DOM et modifier une page
  • Tu sais réagir aux clics et événements
  • Prochaine étape : API du navigateur, requêtes réseau (fetch), frameworks Vue.js ou React