Quiz sur la grammaire et le vocabulaire B1

Quiz Français B1

body {
font-family: ‘Segoe UI’, Tahoma, Geneva, Verdana, sans-serif;
max-width: 100%;
margin: 0 auto;
padding: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
}
h1, h2, h3 {
color: #2c3e50;
}
.container {
background: rgba(255, 255, 255, 0.95);
padding: 30px;
border-radius: 15px;
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
backdrop-filter: blur(10px);
max-width: 100%;
margin: 0 auto;
}
.subscription-form {
background: linear-gradient(135deg, #e8f4f8 0%, #d4f1f4 100%);
padding: 25px;
border-radius: 12px;
margin-bottom: 30px;
border: 1px solid rgba(52, 152, 219, 0.2);
}
.exercise-container {
display: none;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #2c3e50;
}
input, select, textarea {
width: 100%;
padding: 12px;
border: 2px solid #e9ecef;
border-radius: 8px;
font-size: 16px;
transition: border-color 0.3s ease;
}
input:focus, select:focus, textarea:focus {
outline: none;
border-color: #3498db;
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
}
button {
background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
color: white;
border: none;
padding: 15px 25px;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3);
}
button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(52, 152, 219, 0.4);
}
.question {
margin-bottom: 25px;
padding: 25px;
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
border-radius: 12px;
border-left: 5px solid #3498db;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}
.question-number {
font-weight: bold;
color: #2c3e50;
margin-bottom: 12px;
font-size: 18px;
}
.question-text {
font-size: 16px;
margin-bottom: 15px;
line-height: 1.6;
color: #2c3e50;
}
.question-type {
background: #3498db;
color: white;
padding: 4px 12px;
border-radius: 20px;
font-size: 12px;
font-weight: bold;
display: inline-block;
margin-bottom: 10px;
}
.options {
display: grid;
gap: 12px;
}
.option {
display: flex;
align-items: center;
padding: 12px;
background: white;
border: 2px solid #e9ecef;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
}
.option:hover {
border-color: #3498db;
background: linear-gradient(135deg, #f0f8ff 0%, #e6f3ff 100%);
transform: translateX(5px);
}
.option input[type=”radio”], .option input[type=”checkbox”] {
margin-right: 12px;
width: auto;
transform: scale(1.2);
}
.option.correct {
background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%);
border-color: #28a745;
}
.option.incorrect {
background: linear-gradient(135deg, #f8d7da 0%, #f1b0b7 100%);
border-color: #dc3545;
}
.option.correct-answer {
background: linear-gradient(135deg, #d1ecf1 0%, #bee5eb 100%);
border-color: #17a2b8;
}
.fill-blank {
background: white;
border: 2px solid #3498db;
border-radius: 6px;
padding: 8px 12px;
margin: 0 5px;
min-width: 120px;
text-align: center;
font-weight: bold;
}
.result {
margin-top: 30px;
padding: 25px;
background: linear-gradient(135deg, #eafaf1 0%, #d4f1de 100%);
border-radius: 12px;
display: none;
border: 1px solid rgba(40, 167, 69, 0.2);
}
.certificate {
text-align: center;
margin-top: 30px;
padding: 25px;
border: 3px solid #2c3e50;
border-radius: 12px;
display: none;
background: white;
}
.error {
color: #dc3545;
font-size: 14px;
margin-top: 5px;
}
.progress-bar {
width: 100%;
height: 25px;
background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
border-radius: 15px;
margin-bottom: 25px;
overflow: hidden;
box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
}
.progress-fill {
height: 100%;
background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
border-radius: 15px;
transition: width 0.5s ease;
width: 0%;
box-shadow: 0 2px 4px rgba(40, 167, 69, 0.3);
}
#certificatePreview {
position: relative;
width: 100%;
height: 500px;
background: linear-gradient(135deg, #fff 0%, #f8f9fa 100%);
border: 12px solid transparent;
border-image: linear-gradient(45deg, #3498db, #2980b9, #1abc9c, #16a085, #27ae60) 1;
box-sizing: border-box;
overflow: hidden;
margin-bottom: 25px;
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
}
.certificate-content {
position: relative;
z-index: 1;
padding: 25px;
width: 100%;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.certificate-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.certificate-title {
flex-grow: 1;
text-align: center;
}
.certificate-logo {
width: 140px;
height: 70px;
background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
font-size: 18px;
}
.certificate-footer {
display: flex;
justify-content: space-between;
align-items: flex-end;
}
.certificate-qr {
width: 120px;
height: 120px;
display: flex;
justify-content: center;
align-items: center;
background: #f9f9f9;
border: 2px solid #dee2e6;
border-radius: 8px;
}
.certificate-signature {
flex-grow: 1;
text-align: center;
}
.loading {
display: none;
margin-top: 15px;
font-style: italic;
color: #6c757d;
text-align: center;
}
.instruction-box {
background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%);
border: 2px solid #ffeaa7;
border-radius: 12px;
padding: 20px;
margin-bottom: 25px;
}
.theme-section {
margin-bottom: 35px;
padding: 25px;
background: linear-gradient(135deg, #f1f3f4 0%, #e8eaed 100%);
border-radius: 12px;
border-left: 6px solid #e74c3c;
box-shadow: 0 4px 15px rgba(0,0,0,0.05);
}
.theme-title {
color: #e74c3c;
font-size: 20px;
font-weight: bold;
margin-bottom: 20px;
text-transform: uppercase;
letter-spacing: 1px;
}
.multiple-choice-container {
display: grid;
gap: 10px;
}
.score-display {
font-size: 24px;
font-weight: bold;
color: #27ae60;
text-align: center;
margin: 20px 0;
padding: 15px;
background: linear-gradient(135deg, #d4f1de 0%, #c3e6cb 100%);
border-radius: 10px;
}

🎯 Quiz de Français – Niveau B1

Testez vos connaissances sur la grammaire française de niveau intermédiaire ! Ce quiz couvre les points essentiels du niveau B1.

🏆 Quiz Français B1 – Grammaire et Lexique

📋 Instructions: Ce quiz évalue vos compétences en français niveau B1 :

  • 🔹 Questions à choix multiples
  • 🔹 Complétion de phrases
  • 🔹 Questions à réponses multiples
  • 🔹 Conjugaisons et accords

Thèmes B1: Mise en relief • Opposition • Futur simple • Subjonctif présent • Pronoms possessifs • Projets • Passé composé/Imparfait • Indicateurs temporels • Accord du participe passé • Généalogie

✨ Thème 1: La Mise en Relief
CHOIX MULTIPLE
Question 1
Quelle phrase met correctement en relief le complément?



COMPLÉTION
Question 2
Complétez la mise en relief:
Marie a gagné le concours.

RÉPONSES MULTIPLES
Question 3
Quelles structures permettent la mise en relief? (Plusieurs réponses)



⚖️ Thème 2: Exprimer l’Opposition
CHOIX MULTIPLE
Question 4
“_____ il soit fatigué, il continue à travailler.”



COMPLÉTION
Question 5
Complétez avec les mots d’opposition:
“Il pleut, nous sortirons la pluie.”

RÉPONSES MULTIPLES
Question 6
Quels mots expriment l’opposition? (Plusieurs réponses)



⏭️ Thème 3: Le Futur Simple
CHOIX MULTIPLE
Question 7
Conjuguez “voir” à la 1ère personne du singulier au futur simple:



COMPLÉTION
Question 8
Conjuguez au futur simple:
“Demain, je mes devoirs, j’ du temps libre et j’ au cinéma.”

RÉPONSES MULTIPLES
Question 9
Quels verbes sont correctement conjugués au futur? (Plusieurs réponses)



❗ Thème 4: Il faut que / Il ne faut pas que
CHOIX MULTIPLE
Question 10
“Il faut que tu _____ à l’heure.”



COMPLÉTION
Question 11
Complétez avec le subjonctif:
“Il faut que vous et il ne faut pas que vous trop tôt.”

RÉPONSES MULTIPLES
Question 12
Quelles phrases sont correctes? (Plusieurs réponses)



🔄 Thème 5: Le Subjonctif Présent
CHOIX MULTIPLE
Question 13
“Je doute qu’il _____ la vérité.”



COMPLÉTION
Question 14
Conjuguez au subjonctif présent:
“J’ai peur que tu ne pas venir et que tu des problèmes.”

RÉPONSES MULTIPLES
Question 15
Après quelles expressions utilise-t-on le subjonctif? (Plusieurs réponses)



👥 Thème 6: Les Pronoms Possessifs
CHOIX MULTIPLE
Question 16
“Cette voiture est à moi, c’est _____.”



COMPLÉTION
Question 17
Complétez avec les pronoms possessifs:
“Vos enfants sont sages, sont très turbulents !”

RÉPONSES MULTIPLES
Question 18
Quels sont les pronoms possessifs féminins pluriels? (Plusieurs réponses)



🎯 Thème 7: Parler de ses Projets
CHOIX MULTIPLE
Question 19
Quelle expression exprime un projet futur?



COMPLÉTION
Question 20
Complétez avec les verbes de projet:
“Elle étudier la médecine et il de voyager.”

RÉPONSES MULTIPLES
Question 21
Quelles expressions servent à parler de projets? (Plusieurs réponses)



⏱️ Thème 8: Passé Composé / Imparfait
CHOIX MULTIPLE
Question 22
“Quand j’étais petit, je _____ beaucoup de livres.”



COMPLÉTION
Question 23
Choisissez le bon temps:
“Il quand le téléphone .”

RÉPONSES MULTIPLES
Question 24
Quand utilise-t-on l’imparfait? (Plusieurs réponses)



⏰ Thème 9: Les Indicateurs Temporels
CHOIX MULTIPLE
Question 25
Quel indicateur temporel indique la simultanéité?



COMPLÉTION
Question 26
Complétez la chronologie:
“, il s’est levé, il a pris son petit-déjeuner et il est parti.”

RÉPONSES MULTIPLES
Question 27
Quels mots indiquent l’antériorité? (Plusieurs réponses)



✍️ Thème 10: Accord du Participe Passé avec Avoir
CHOIX MULTIPLE
Question 28
“Les fleurs que j’ai _____”



COMPLÉTION
Question 29
Accordez le participe passé:
“La pomme qu’il a et les personnes qu’elle a .”

RÉPONSES MULTIPLES
Question 30
Dans quels cas le participe passé s’accorde-t-il avec avoir? (Plusieurs réponses)



👨‍👩‍👧‍👦 Thème 11: Le Lexique de la Généalogie
CHOIX MULTIPLE
Question 31
Comment appelle-t-on la sœur de votre père?



COMPLÉTION
Question 32
Complétez les termes de parenté:
“Mon et ma viennent dîner.”

RÉPONSES MULTIPLES
Question 33
Quels sont des termes de parenté par alliance? (Plusieurs réponses)



CHOIX MULTIPLE
Question 34
Que représente un “arbre généalogique”?



COMPLÉTION
Question 35
Complétez le vocabulaire généalogique:
“Mon était agriculteur et ses vivent encore dans la région.”

📊 Résultats de votre Quiz B1

🎓 Certificat de Réussite – Niveau B1

CERTIFICAT DE MAÎTRISE

Français B1 – Niveau Intermédiaire

Ce certificat atteste que

a démontré sa maîtrise du français niveau B1
dans les domaines suivants:

Mise en relief • Opposition • Futur simple • Subjonctif présent
Pronoms possessifs • Expression des projets • Passé composé/Imparfait
Indicateurs temporels • Accord du participe passé • Généalogie

Score obtenu:

Date:

⏳ Génération du PDF en cours…

document.addEventListener(‘DOMContentLoaded’, function() {
// Configuration du quiz B1
const totalQuestions = 35;
const passingScore = 70;

// Références aux éléments DOM
const subscriptionForm = document.getElementById(‘subscriptionForm’);
const exerciseContainer = document.getElementById(‘exerciseContainer’);
const startButton = document.getElementById(‘startButton’);
const verifyButton = document.getElementById(‘verifyButton’);
const resultContainer = document.getElementById(‘resultContainer’);
const scoreDisplay = document.getElementById(‘scoreDisplay’);
const resultText = document.getElementById(‘resultText’);
const mistakesContainer = document.getElementById(‘mistakesContainer’);
const showCertificateButton = document.getElementById(‘showCertificateButton’);
const certificateContainer = document.getElementById(‘certificateContainer’);
const downloadCertificateButton = document.getElementById(‘downloadCertificateButton’);
const pdfLoading = document.getElementById(‘pdfLoading’);
const progressFill = document.getElementById(‘progressFill’);

// Données utilisateur
let userData = {
prenom: ”,
nom: ”,
email: ”,
score: 0
};

// Démarrer le quiz
startButton.addEventListener(‘click’, function() {
if (validateForm()) {
subscriptionForm.style.display = ‘none’;
exerciseContainer.style.display = ‘block’;
exerciseContainer.scrollIntoView({ behavior: ‘smooth’ });
}
});

// Validation du formulaire
function validateForm() {
const prenom = document.getElementById(‘prenom’).value.trim();
const nom = document.getElementById(‘nom’).value.trim();
const email = document.getElementById(‘email’).value.trim();
const subscribe = document.getElementById(‘subscribe’).checked;

clearErrors();

let isValid = true;

if (!prenom) {
showError(‘prenomError’, ‘Veuillez entrer votre prénom’);
isValid = false;
}

if (!nom) {
showError(‘nomError’, ‘Veuillez entrer votre nom’);
isValid = false;
}

if (!email) {
showError(‘emailError’, ‘Veuillez entrer votre email’);
isValid = false;
} else if (!/^[^s@]+@[^s@]+.[^s@]+$/.test(email)) {
showError(‘emailError’, ‘Veuillez entrer un email valide’);
isValid = false;
}

if (!subscribe) {
showError(‘subscribeError’, ‘Veuillez accepter de vous abonner’);
isValid = false;
}

if (isValid) {
userData.prenom = prenom;
userData.nom = nom;
userData.email = email;
}

return isValid;
}

function clearErrors() {
const errorElements = [‘prenomError’, ‘nomError’, ‘emailError’, ‘subscribeError’];
errorElements.forEach(id => {
document.getElementById(id).textContent = ”;
});
}

function showError(elementId, message) {
document.getElementById(elementId).textContent = message;
}

// Mettre à jour la barre de progression
function updateProgress() {
const answeredQuestions = getAnsweredQuestionsCount();
const progress = (answeredQuestions / totalQuestions) * 100;
progressFill.style.width = progress + ‘%’;
}

function getAnsweredQuestionsCount() {
let count = 0;

for (let i = 1; i 0) {
let allFilled = true;
fillBlanks.forEach(blank => {
if (!blank.value.trim()) {
allFilled = false;
}
});
if (allFilled) count++;
}
}
}

return count;
}

// Écouter les changements
document.addEventListener(‘change’, updateProgress);
document.addEventListener(‘input’, updateProgress);

// Vérifier les réponses
verifyButton.addEventListener(‘click’, function() {
const results = checkAnswers();
displayResults(results);
});

function checkAnswers() {
let correctAnswers = 0;
const mistakes = [];
const questions = document.querySelectorAll(‘.question[data-answer]’);

questions.forEach((question, index) => {
const questionNum = index + 1;
const type = question.dataset.type;
const correctAnswer = question.dataset.answer;

let isCorrect = false;
let userAnswer = ”;
let correctText = ”;

if (type === ‘single’) {
const selectedRadio = question.querySelector(`input[type=”radio”]:checked`);
if (selectedRadio) {
userAnswer = selectedRadio.value;
isCorrect = userAnswer === correctAnswer;

// Marquer visuellement les réponses
const options = question.querySelectorAll(‘.option’);
options.forEach(option => {
option.classList.remove(‘correct’, ‘incorrect’, ‘correct-answer’);
});

if (isCorrect) {
selectedRadio.closest(‘.option’).classList.add(‘correct’);
} else {
selectedRadio.closest(‘.option’).classList.add(‘incorrect’);
const correctOption = question.querySelector(`input[value=”${correctAnswer}”]`);
if (correctOption) {
correctOption.closest(‘.option’).classList.add(‘correct-answer’);
}
}
}
} else if (type === ‘multiple’) {
const selectedCheckboxes = question.querySelectorAll(`input[type=”checkbox”]:checked`);
const selectedValues = Array.from(selectedCheckboxes).map(cb => cb.value).sort();
const correctValues = correctAnswer.split(‘,’).sort();

isCorrect = JSON.stringify(selectedValues) === JSON.stringify(correctValues);
userAnswer = selectedValues.join(‘, ‘);
correctText = correctValues.join(‘, ‘);

// Marquer visuellement
const allCheckboxes = question.querySelectorAll(‘input[type=”checkbox”]’);
allCheckboxes.forEach(cb => {
const option = cb.closest(‘.option’);
option.classList.remove(‘correct’, ‘incorrect’, ‘correct-answer’);

if (cb.checked) {
if (correctValues.includes(cb.value)) {
option.classList.add(‘correct’);
} else {
option.classList.add(‘incorrect’);
}
} else if (correctValues.includes(cb.value)) {
option.classList.add(‘correct-answer’);
}
});
} else if (type === ‘fill’) {
const fillBlanks = question.querySelectorAll(‘.fill-blank’);
const correctValues = correctAnswer.split(‘,’);
let allCorrect = true;

fillBlanks.forEach((blank, i) => {
const userValue = blank.value.trim().toLowerCase();
const expectedValue = correctValues[i].trim().toLowerCase();

if (userValue !== expectedValue) {
allCorrect = false;
blank.style.borderColor = ‘#dc3545’;
blank.style.backgroundColor = ‘#f8d7da’;
} else {
blank.style.borderColor = ‘#28a745’;
blank.style.backgroundColor = ‘#d4edda’;
}
});

isCorrect = allCorrect;
userAnswer = Array.from(fillBlanks).map(blank => blank.value.trim()).join(‘, ‘);
correctText = correctAnswer.replace(/,/g, ‘, ‘);
}

if (isCorrect) {
correctAnswers++;
} else {
const questionText = question.querySelector(‘.question-text’).textContent.trim();
mistakes.push({
number: questionNum,
question: questionText,
userAnswer: userAnswer || ‘Pas de réponse’,
correctAnswer: correctText || correctAnswer
});
}
});

const percentage = Math.round((correctAnswers / totalQuestions) * 100);
userData.score = percentage;

return {
correct: correctAnswers,
total: totalQuestions,
percentage: percentage,
mistakes: mistakes
};
}

function displayResults(results) {
scoreDisplay.textContent = `${results.percentage}%`;

let message = ”;
let showCertificate = false;

if (results.percentage >= 90) {
message = ‘🎉 Excellent ! Vous maîtrisez parfaitement le français B1 !’;
showCertificate = true;
scoreDisplay.style.color = ‘#27ae60’;
} else if (results.percentage >= passingScore) {
message = ‘👍 Très bien ! Vous avez un bon niveau B1 en français.’;
showCertificate = true;
scoreDisplay.style.color = ‘#27ae60’;
} else if (results.percentage >= 50) {
message = ‘📚 Pas mal ! Continuez à pratiquer pour améliorer votre niveau B1.’;
scoreDisplay.style.color = ‘#f39c12’;
} else {
message = ‘💪 Il faut encore travailler. Révisez les points de grammaire B1 et recommencez !’;
scoreDisplay.style.color = ‘#e74c3c’;
}

resultText.textContent = message;

// Afficher les erreurs
if (results.mistakes.length > 0) {
let mistakesHtml = ‘

📝 Questions à revoir :

‘;
results.mistakes.forEach(mistake => {
mistakesHtml += `

Question ${mistake.number}: ${mistake.question}
Votre réponse: ${mistake.userAnswer}
Réponse correcte: ${mistake.correctAnswer}

`;
});
mistakesContainer.innerHTML = mistakesHtml;
} else {
mistakesContainer.innerHTML = ‘

🎯 Parfait ! Toutes vos réponses sont correctes !

‘;
}

if (showCertificate) {
showCertificateButton.style.display = ‘inline-block’;
}

resultContainer.style.display = ‘block’;
resultContainer.scrollIntoView({ behavior: ‘smooth’ });

// Désactiver le bouton de vérification
verifyButton.disabled = true;
verifyButton.textContent = ‘✅ Réponses vérifiées’;
verifyButton.style.opacity = ‘0.6’;
}

// Afficher le certificat
showCertificateButton.addEventListener(‘click’, function() {
document.getElementById(‘certificateName’).textContent = `${userData.prenom} ${userData.nom}`;
document.getElementById(‘certificateScore’).textContent = `${userData.score}%`;
document.getElementById(‘certificateDate’).textContent = new Date().toLocaleDateString(‘fr-FR’);

certificateContainer.style.display = ‘block’;
certificateContainer.scrollIntoView({ behavior: ‘smooth’ });
});

// Télécharger le certificat PDF
downloadCertificateButton.addEventListener(‘click’, function() {
generatePDF();
});

function generatePDF() {
pdfLoading.style.display = ‘block’;
downloadCertificateButton.disabled = true;

const element = document.getElementById(‘certificatePreview’);

html2canvas(element, {
scale: 2,
useCORS: true,
allowTaint: true,
backgroundColor: ‘#ffffff’
}).then(canvas => {
const imgData = canvas.toDataURL(‘image/png’);
const { jsPDF } = window.jspdf;

// Format A4 paysage
const pdf = new jsPDF(‘landscape’, ‘mm’, ‘a4’);
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();

// Calculer les dimensions pour centrer l’image
const imgWidth = pdfWidth – 20; // Marges de 10mm de chaque côté
const imgHeight = (canvas.height * imgWidth) / canvas.width;

const x = 10; // Marge gauche
const y = (pdfHeight – imgHeight) / 2; // Centrer verticalement

pdf.addImage(imgData, ‘PNG’, x, y, imgWidth, imgHeight);

// Métadonnées du PDF
pdf.setProperties({
title: `Certificat Français B1 – ${userData.prenom} ${userData.nom}`,
subject: ‘Certificat de maîtrise du français niveau B1’,
author: ‘Français Langue Française’,
creator: ‘Quiz B1 Generator’
});

const filename = `Certificat_Francais_B1_${userData.prenom}_${userData.nom}_${userData.score}pct.pdf`;
pdf.save(filename);

pdfLoading.style.display = ‘none’;
downloadCertificateButton.disabled = false;
}).catch(error => {
console.error(‘Erreur lors de la génération du PDF:’, error);
alert(‘Erreur lors de la génération du PDF. Veuillez réessayer.’);
pdfLoading.style.display = ‘none’;
downloadCertificateButton.disabled = false;
});
}

// Fonction pour normaliser les réponses (ignorer les accents, majuscules, espaces)
function normalizeAnswer(answer) {
return answer.toLowerCase()
.trim()
.normalize(‘NFD’)
.replace(/[u0300-u036f]/g, ”) // Supprimer les accents
.replace(/s+/g, ‘ ‘); // Normaliser les espaces
}

// Améliorer la vérification des réponses à remplir
function checkFillAnswer(userAnswer, correctAnswer) {
const normalizedUser = normalizeAnswer(userAnswer);
const normalizedCorrect = normalizeAnswer(correctAnswer);

// Vérification exacte
if (normalizedUser === normalizedCorrect) {
return true;
}

// Vérifications alternatives pour certaines réponses
const alternatives = {
‘cest’: [‘c’est’, ‘cest’],
‘dabord’: [‘d’abord’, ‘dabord’],
‘arrriere-grand-pere’: [‘arrière-grand-père’, ‘arriere-grand-pere’, ‘arrière grand père’],
‘belle-fille’: [‘belle-fille’, ‘belle fille’, ‘bellefille’]
};

for (const [key, values] of Object.entries(alternatives)) {
if (values.some(alt => normalizeAnswer(alt) === normalizedCorrect)) {
return values.some(alt => normalizeAnswer(alt) === normalizedUser);
}
}

return false;
}

// Initialiser la barre de progression
updateProgress();

// Ajouter des animations aux éléments
function addAnimations() {
const questions = document.querySelectorAll(‘.question’);
questions.forEach((question, index) => {
question.style.opacity = ‘0’;
question.style.transform = ‘translateY(20px)’;
question.style.transition = ‘all 0.5s ease’;

setTimeout(() => {
question.style.opacity = ‘1’;
question.style.transform = ‘translateY(0)’;
}, index * 100);
});
}

// Ajouter un effet de survol aux options
document.querySelectorAll(‘.option’).forEach(option => {
option.addEventListener(‘mouseenter’, function() {
this.style.transform = ‘translateX(5px)’;
});

option.addEventListener(‘mouseleave’, function() {
if (!this.classList.contains(‘correct’) &&
!this.classList.contains(‘incorrect’) &&
!this.classList.contains(‘correct-answer’)) {
this.style.transform = ‘translateX(0)’;
}
});
});

// Démarrer les animations quand l’exercice est affiché
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.target.id === ‘exerciseContainer’ &&
mutation.target.style.display === ‘block’) {
setTimeout(addAnimations, 500);
}
});
});

observer.observe(exerciseContainer, {
attributes: true,
attributeFilter: [‘style’]
});

// Validation en temps réel pour les champs de saisie
document.querySelectorAll(‘.fill-blank’).forEach(input => {
input.addEventListener(‘blur’, function() {
const question = this.closest(‘.question’);
if (question && question.dataset.type === ‘fill’) {
// Réinitialiser le style
this.style.borderColor = ‘#3498db’;
this.style.backgroundColor = ‘white’;
}
});
});
});