353 lines
21 KiB
JavaScript
353 lines
21 KiB
JavaScript
/**
|
||
* quiz.js – U14 Mini-Quiz
|
||
* ─────────────────────────────────────────────────────────────────────────
|
||
* • 50 Fragen als Objekt-Array
|
||
* • Jedes Mal 3 zufällige Fragen aus dem Pool
|
||
* • Dynamischer Aufbau per createElement (kein statisches HTML)
|
||
* • Direktes DOM-Feedback (richtig ✅ / falsch ❌, ohne alert())
|
||
* • Buttons nach Antwort deaktiviert (kein doppeltes Punkten)
|
||
* • Punktezähler sichtbar während dem Quiz
|
||
* • Auswertungsscreen mit unterschiedlichen Nachrichten je Ergebnis
|
||
* • Highscore (Anzahl perfekter Runden) in localStorage
|
||
* • "Neu starten"-Button zieht neue 3 Fragen
|
||
* ─────────────────────────────────────────────────────────────────────────
|
||
*/
|
||
|
||
(function () {
|
||
'use strict';
|
||
|
||
/* ═══════════════════════════════════════════════════════════════════════
|
||
Fragen-Pool (50 Fragen)
|
||
═══════════════════════════════════════════════════════════════════════ */
|
||
const ALLE_FRAGEN = [
|
||
{ frage: 'Welcher Planet ist der Sonne am nächsten?', antworten: ['Venus', 'Merkur', 'Mars'], richtig: 'Merkur' },
|
||
{ frage: 'Wie viele Kontinente gibt es auf der Erde?', antworten: ['5', '6', '7'], richtig: '7' },
|
||
{ frage: 'Welches Organ pumpt Blut durch den Körper?', antworten: ['Lunge', 'Herz', 'Leber'], richtig: 'Herz' },
|
||
{ frage: 'In welchem Land steht der Eiffelturm?', antworten: ['Frankreich', 'Italien', 'Spanien'], richtig: 'Frankreich' },
|
||
{ frage: 'Wie heißt die Hauptstadt von Deutschland?', antworten: ['München', 'Hamburg', 'Berlin'], richtig: 'Berlin' },
|
||
{ frage: 'Welches Tier ist das größte lebende Säugetier?', antworten: ['Elefant', 'Blauwal', 'Giraffe'], richtig: 'Blauwal' },
|
||
{ frage: 'Wie viele Beine hat eine Spinne?', antworten: ['6', '8', '10'], richtig: '8' },
|
||
{ frage: 'Welcher Stoff ist für die Atmung des Menschen wichtig?', antworten: ['Sauerstoff', 'Stickstoff', 'Helium'], richtig: 'Sauerstoff' },
|
||
{ frage: 'Wie heißt der größte Ozean der Erde?', antworten: ['Atlantischer Ozean', 'Indischer Ozean', 'Pazifischer Ozean'], richtig: 'Pazifischer Ozean' },
|
||
{ frage: 'Welche Farbe entsteht, wenn man Blau und Gelb mischt?', antworten: ['Grün', 'Orange', 'Lila'], richtig: 'Grün' },
|
||
{ frage: 'Wie viele Minuten hat eine Stunde?', antworten: ['50', '60', '100'], richtig: '60' },
|
||
{ frage: 'Welcher Wochentag kommt nach Freitag?', antworten: ['Donnerstag', 'Samstag', 'Sonntag'], richtig: 'Samstag' },
|
||
{ frage: 'Wie heißt der natürliche Satellit der Erde?', antworten: ['Sonne', 'Mond', 'Mars'], richtig: 'Mond' },
|
||
{ frage: 'Welche Sprache spricht man hauptsächlich in Brasilien?', antworten: ['Spanisch', 'Portugiesisch', 'Französisch'], richtig: 'Portugiesisch' },
|
||
{ frage: 'Wie viele Bundesländer hat Deutschland?', antworten: ['14', '16', '18'], richtig: '16' },
|
||
{ frage: 'Welcher Fluss fließt durch Köln?', antworten: ['Donau', 'Rhein', 'Elbe'], richtig: 'Rhein' },
|
||
{ frage: 'Wer schrieb das Drama „Romeo und Julia"?', antworten: ['William Shakespeare', 'Johann Wolfgang von Goethe', 'Friedrich Schiller'], richtig: 'William Shakespeare' },
|
||
{ frage: 'Welche Zahl ist eine Primzahl?', antworten: ['9', '11', '15'], richtig: '11' },
|
||
{ frage: 'Was ist H₂O?', antworten: ['Salz', 'Wasser', 'Kohlendioxid'], richtig: 'Wasser' },
|
||
{ frage: 'Wie nennt man Tiere, die nur Pflanzen fressen?', antworten: ['Pflanzenfresser', 'Fleischfresser', 'Allesfresser'], richtig: 'Pflanzenfresser' },
|
||
{ frage: 'Welches Land hat die Form eines Stiefels?', antworten: ['Italien', 'Griechenland', 'Portugal'], richtig: 'Italien' },
|
||
{ frage: 'Welches Metall ist bei Raumtemperatur flüssig?', antworten: ['Eisen', 'Quecksilber', 'Gold'], richtig: 'Quecksilber' },
|
||
{ frage: 'Wie heißt die Hauptstadt von Spanien?', antworten: ['Barcelona', 'Madrid', 'Valencia'], richtig: 'Madrid' },
|
||
{ frage: 'Welcher Planet wird auch der rote Planet genannt?', antworten: ['Mars', 'Jupiter', 'Saturn'], richtig: 'Mars' },
|
||
{ frage: 'Was misst ein Thermometer?', antworten: ['Temperatur', 'Geschwindigkeit', 'Gewicht'], richtig: 'Temperatur' },
|
||
{ frage: 'Welche Jahreszeit folgt auf den Winter?', antworten: ['Herbst', 'Sommer', 'Frühling'], richtig: 'Frühling' },
|
||
{ frage: 'Welches Tier legt Eier?', antworten: ['Hund', 'Huhn', 'Kuh'], richtig: 'Huhn' },
|
||
{ frage: 'Wie viele Seiten hat ein Dreieck?', antworten: ['3', '4', '5'], richtig: '3' },
|
||
{ frage: 'Welcher Kontinent ist der flächenmäßig größte?', antworten: ['Afrika', 'Asien', 'Europa'], richtig: 'Asien' },
|
||
{ frage: 'Wie heißt das kleinste Bundesland Deutschlands?', antworten: ['Bremen', 'Saarland', 'Hamburg'], richtig: 'Bremen' },
|
||
{ frage: 'Welches Instrument hat Tasten, Saiten und Hämmer?', antworten: ['Gitarre', 'Klavier', 'Trompete'], richtig: 'Klavier' },
|
||
{ frage: 'Welche Sportart spielt man mit Schläger und Federball?', antworten: ['Tennis', 'Badminton', 'Basketball'], richtig: 'Badminton' },
|
||
{ frage: 'Wie viele Spieler stehen pro Fußballmannschaft auf dem Feld?', antworten: ['9', '10', '11'], richtig: '11' },
|
||
{ frage: 'Welche Einheit verwendet man für elektrische Spannung?', antworten: ['Volt', 'Meter', 'Liter'], richtig: 'Volt' },
|
||
{ frage: 'Was ist die Hauptstadt von Österreich?', antworten: ['Wien', 'Graz', 'Salzburg'], richtig: 'Wien' },
|
||
{ frage: 'Welches Gas nehmen Pflanzen bei der Fotosynthese auf?', antworten: ['Sauerstoff', 'Kohlendioxid', 'Wasserstoff'], richtig: 'Kohlendioxid' },
|
||
{ frage: 'Wie heißt der höchste Berg der Erde?', antworten: ['Mount Everest', 'Kilimandscharo', 'Zugspitze'], richtig: 'Mount Everest' },
|
||
{ frage: 'Welche Farbe hat Chlorophyll überwiegend?', antworten: ['Rot', 'Grün', 'Blau'], richtig: 'Grün' },
|
||
{ frage: 'Welches Land liegt nicht in Europa?', antworten: ['Norwegen', 'Kanada', 'Polen'], richtig: 'Kanada' },
|
||
{ frage: 'Was ist ein Synonym für „schnell"?', antworten: ['rasch', 'langsam', 'leise'], richtig: 'rasch' },
|
||
{ frage: 'Welcher Komponist schrieb die 9. Sinfonie?', antworten: ['Ludwig van Beethoven', 'Wolfgang Amadeus Mozart', 'Johann Sebastian Bach'], richtig: 'Ludwig van Beethoven' },
|
||
{ frage: 'Welches Tier wird oft als König der Tiere bezeichnet?', antworten: ['Tiger', 'Löwe', 'Bär'], richtig: 'Löwe' },
|
||
{ frage: 'Wie viele Planeten hat unser Sonnensystem?', antworten: ['7', '8', '9'], richtig: '8' },
|
||
{ frage: 'Welche Stadt ist bekannt für das Kolosseum?', antworten: ['Rom', 'Athen', 'Paris'], richtig: 'Rom' },
|
||
{ frage: 'Was ist die Hauptstadt der Schweiz?', antworten: ['Zürich', 'Genf', 'Bern'], richtig: 'Bern' },
|
||
{ frage: 'Welche Form hat ein Rad normalerweise?', antworten: ['quadratisch', 'rund', 'dreieckig'], richtig: 'rund' },
|
||
{ frage: 'Welcher Sinn ist mit der Nase verbunden?', antworten: ['Riechen', 'Hören', 'Sehen'], richtig: 'Riechen' },
|
||
{ frage: 'Wie nennt man gefrorenes Wasser?', antworten: ['Dampf', 'Eis', 'Nebel'], richtig: 'Eis' },
|
||
{ frage: 'Welcher Kontinent liegt südlich von Europa?', antworten: ['Afrika', 'Asien', 'Nordamerika'], richtig: 'Afrika' },
|
||
{ frage: 'Was ist das Gegenteil von „hell"?', antworten: ['dunkel', 'warm', 'laut'], richtig: 'dunkel' },
|
||
];
|
||
|
||
const FRAGEN_PRO_RUNDE = 3;
|
||
const HIGHSCORE_KEY = 'quiz_highscore_v1';
|
||
|
||
/* ═══════════════════════════════════════════════════════════════════════
|
||
State
|
||
═══════════════════════════════════════════════════════════════════════ */
|
||
let rundenFragen = []; // die 3 gezogenen Fragen dieser Runde
|
||
let aktuelleIdx = 0; // welche Frage gerade angezeigt wird
|
||
let punkte = 0;
|
||
let gegebeneAntworten = []; // gespeicherte Antworten des Nutzers
|
||
|
||
/* ═══════════════════════════════════════════════════════════════════════
|
||
Utility
|
||
═══════════════════════════════════════════════════════════════════════ */
|
||
|
||
/** Fisher-Yates Shuffle – mischt Array in-place */
|
||
function shuffle (arr) {
|
||
for (let i = arr.length - 1; i > 0; i--) {
|
||
const j = Math.floor(Math.random() * (i + 1));
|
||
[arr[i], arr[j]] = [arr[j], arr[i]];
|
||
}
|
||
return arr;
|
||
}
|
||
|
||
/** Zieht n zufällige Fragen aus dem Pool */
|
||
function zieheZufallsFragen (pool, n) {
|
||
return shuffle([...pool]).slice(0, n);
|
||
}
|
||
|
||
function ladeHighscore () {
|
||
return parseInt(localStorage.getItem(HIGHSCORE_KEY) || '0', 10);
|
||
}
|
||
|
||
function speichereHighscore (wert) {
|
||
const aktuell = ladeHighscore();
|
||
if (wert > aktuell) localStorage.setItem(HIGHSCORE_KEY, String(wert));
|
||
}
|
||
|
||
/* ═══════════════════════════════════════════════════════════════════════
|
||
DOM-Aufbau
|
||
═══════════════════════════════════════════════════════════════════════ */
|
||
const container = document.getElementById('quiz');
|
||
|
||
function baueQuizAuf () {
|
||
rundenFragen = zieheZufallsFragen(ALLE_FRAGEN, FRAGEN_PRO_RUNDE);
|
||
aktuelleIdx = 0;
|
||
punkte = 0;
|
||
gegebeneAntworten = [];
|
||
container.innerHTML = '';
|
||
zeigeAktuelleFrageOderAuswertung();
|
||
}
|
||
|
||
/* ── Fortschrittsleiste + Punkteanzeige ─────────────────────────────── */
|
||
function baueKopfzeile () {
|
||
const kopf = document.createElement('div');
|
||
kopf.className = 'quiz-kopf';
|
||
|
||
const fortschritt = document.createElement('div');
|
||
fortschritt.className = 'quiz-fortschritt';
|
||
|
||
const balkenWrapper = document.createElement('div');
|
||
balkenWrapper.className = 'quiz-balken-wrapper';
|
||
const balken = document.createElement('div');
|
||
balken.className = 'quiz-balken';
|
||
const prozent = Math.round((aktuelleIdx / FRAGEN_PRO_RUNDE) * 100);
|
||
balken.style.width = prozent + '%';
|
||
balkenWrapper.appendChild(balken);
|
||
|
||
const schrittText = document.createElement('span');
|
||
schrittText.className = 'quiz-schritt';
|
||
schrittText.textContent = 'Frage ' + (aktuelleIdx + 1) + ' von ' + FRAGEN_PRO_RUNDE;
|
||
|
||
fortschritt.appendChild(schrittText);
|
||
fortschritt.appendChild(balkenWrapper);
|
||
|
||
const punkteEl = document.createElement('div');
|
||
punkteEl.className = 'quiz-punkte-live';
|
||
punkteEl.textContent = '⭐ ' + punkte + ' Punkt' + (punkte !== 1 ? 'e' : '');
|
||
|
||
kopf.appendChild(fortschritt);
|
||
kopf.appendChild(punkteEl);
|
||
return kopf;
|
||
}
|
||
|
||
/* ── Einzelne Frage ─────────────────────────────────────────────────── */
|
||
function zeigeAktuelleFrageOderAuswertung () {
|
||
container.innerHTML = '';
|
||
|
||
if (aktuelleIdx >= FRAGEN_PRO_RUNDE) {
|
||
zeigeAuswertung();
|
||
return;
|
||
}
|
||
|
||
const frageDaten = rundenFragen[aktuelleIdx];
|
||
|
||
// Kopfzeile
|
||
container.appendChild(baueKopfzeile());
|
||
|
||
// Frage-Card
|
||
const card = document.createElement('div');
|
||
card.className = 'quiz-card';
|
||
|
||
const frageEl = document.createElement('p');
|
||
frageEl.className = 'quiz-frage';
|
||
frageEl.textContent = frageDaten.frage;
|
||
card.appendChild(frageEl);
|
||
|
||
// Antwort-Buttons
|
||
const btnGruppe = document.createElement('div');
|
||
btnGruppe.className = 'quiz-btn-gruppe';
|
||
|
||
// Antworten mischen (damit die richtige nicht immer an erster Stelle ist)
|
||
const gemischteAntworten = shuffle([...frageDaten.antworten]);
|
||
|
||
gemischteAntworten.forEach(function (antwort) {
|
||
const btn = document.createElement('button');
|
||
btn.type = 'button';
|
||
btn.className = 'quiz-antwort-btn';
|
||
btn.textContent = antwort;
|
||
|
||
btn.addEventListener('click', function () {
|
||
verarbeiteAntwort(antwort, frageDaten.richtig, btnGruppe, feedbackEl, weiterBtn);
|
||
});
|
||
|
||
btnGruppe.appendChild(btn);
|
||
});
|
||
|
||
card.appendChild(btnGruppe);
|
||
|
||
// Feedback-Bereich
|
||
const feedbackEl = document.createElement('div');
|
||
feedbackEl.className = 'quiz-feedback';
|
||
feedbackEl.setAttribute('aria-live', 'polite');
|
||
card.appendChild(feedbackEl);
|
||
|
||
// Weiter-Button (anfangs unsichtbar)
|
||
const weiterBtn = document.createElement('button');
|
||
weiterBtn.type = 'button';
|
||
weiterBtn.className = 'btn quiz-weiter-btn';
|
||
weiterBtn.textContent = aktuelleIdx + 1 < FRAGEN_PRO_RUNDE ? 'Nächste Frage →' : 'Auswertung anzeigen 🏁';
|
||
weiterBtn.hidden = true;
|
||
weiterBtn.addEventListener('click', function () {
|
||
aktuelleIdx++;
|
||
zeigeAktuelleFrageOderAuswertung();
|
||
});
|
||
card.appendChild(weiterBtn);
|
||
|
||
container.appendChild(card);
|
||
}
|
||
|
||
/* ── Antwort verarbeiten ────────────────────────────────────────────── */
|
||
function verarbeiteAntwort (gewaehlt, richtig, btnGruppe, feedbackEl, weiterBtn) {
|
||
const richtigGeantwortet = gewaehlt === richtig;
|
||
|
||
if (richtigGeantwortet) punkte++;
|
||
|
||
// Gegebene Antwort speichern
|
||
gegebeneAntworten.push({ gewaehlt, richtig, korrekt: richtigGeantwortet });
|
||
|
||
// Alle Buttons deaktivieren + einfärben
|
||
btnGruppe.querySelectorAll('.quiz-antwort-btn').forEach(function (btn) {
|
||
btn.disabled = true;
|
||
if (btn.textContent === richtig) {
|
||
btn.classList.add('richtig');
|
||
} else if (btn.textContent === gewaehlt && !richtigGeantwortet) {
|
||
btn.classList.add('falsch');
|
||
}
|
||
});
|
||
|
||
// Feedback im DOM anzeigen
|
||
feedbackEl.className = 'quiz-feedback ' + (richtigGeantwortet ? 'quiz-feedback-richtig' : 'quiz-feedback-falsch');
|
||
feedbackEl.textContent = richtigGeantwortet
|
||
? '✅ Richtig! Super gemacht!'
|
||
: '❌ Leider falsch. Die richtige Antwort ist: ' + richtig;
|
||
|
||
// Weiter-Button einblenden
|
||
weiterBtn.hidden = false;
|
||
}
|
||
|
||
/* ── Auswertungsscreen ──────────────────────────────────────────────── */
|
||
function zeigeAuswertung () {
|
||
// Highscore aktualisieren (perfekte Runden zählen)
|
||
const warPerfekt = punkte === FRAGEN_PRO_RUNDE;
|
||
if (warPerfekt) {
|
||
const neuHS = ladeHighscore() + 1;
|
||
speichereHighscore(neuHS);
|
||
}
|
||
|
||
const screen = document.createElement('div');
|
||
screen.className = 'quiz-auswertung';
|
||
|
||
// Emoji je Ergebnis
|
||
const emoji = punkte === FRAGEN_PRO_RUNDE ? '🏆' : punkte >= 2 ? '👏' : '💪';
|
||
|
||
const headline = document.createElement('h2');
|
||
headline.className = 'quiz-auswertung-titel';
|
||
headline.textContent = emoji + ' Ergebnis';
|
||
screen.appendChild(headline);
|
||
|
||
const ergebnis = document.createElement('p');
|
||
ergebnis.className = 'quiz-ergebnis-zahl';
|
||
ergebnis.textContent = 'Du hast ' + punkte + ' von ' + FRAGEN_PRO_RUNDE + ' richtig!';
|
||
screen.appendChild(ergebnis);
|
||
|
||
// Nachricht je Ergebnis
|
||
const nachrichten = {
|
||
0: 'Nicht aufgeben – beim nächsten Mal klappt es! 💪',
|
||
1: 'Schon mal gut! Versuch es nochmal. 🌱',
|
||
2: 'Fast perfekt! Noch eine Runde? 🌟',
|
||
3: 'Perfekt! Du bist ein Wissens-Genie! 🏆✨',
|
||
};
|
||
|
||
const nachricht = document.createElement('p');
|
||
nachricht.className = 'quiz-nachricht';
|
||
nachricht.textContent = nachrichten[punkte] || '';
|
||
screen.appendChild(nachricht);
|
||
|
||
// Highscore
|
||
const hs = ladeHighscore();
|
||
const highscoreEl = document.createElement('p');
|
||
highscoreEl.className = 'quiz-highscore';
|
||
highscoreEl.textContent = '🥇 Perfekte Runden bisher: ' + hs;
|
||
screen.appendChild(highscoreEl);
|
||
|
||
// Fragen-Rückblick
|
||
const rueckblick = document.createElement('div');
|
||
rueckblick.className = 'quiz-rueckblick';
|
||
const rueckblickTitel = document.createElement('h3');
|
||
rueckblickTitel.textContent = '📋 Deine Antworten';
|
||
rueckblick.appendChild(rueckblickTitel);
|
||
|
||
// Gespeicherte Antworten auslesen und anzeigen
|
||
rundenFragen.forEach(function (f, i) {
|
||
const antwortDaten = gegebeneAntworten[i];
|
||
const item = document.createElement('div');
|
||
item.className = 'quiz-rueckblick-item';
|
||
|
||
if (antwortDaten.korrekt) {
|
||
item.innerHTML =
|
||
'<span class="rb-nr">' + (i + 1) + '.</span>' +
|
||
'<span class="rb-frage">' + f.frage + '</span>' +
|
||
'<span class="rb-richtig">✅ ' + antwortDaten.gewaehlt + '</span>';
|
||
} else {
|
||
item.innerHTML =
|
||
'<span class="rb-nr">' + (i + 1) + '.</span>' +
|
||
'<span class="rb-frage">' + f.frage + '</span>' +
|
||
'<span class="rb-falsch-wrap">' +
|
||
'<span class="rb-falsch">❌ ' + antwortDaten.gewaehlt + '</span>' +
|
||
'<span class="rb-richtig-klein">✅ ' + antwortDaten.richtig + '</span>' +
|
||
'</span>';
|
||
}
|
||
rueckblick.appendChild(item);
|
||
});
|
||
screen.appendChild(rueckblick);
|
||
|
||
// Neu-starten-Button
|
||
const neuBtn = document.createElement('button');
|
||
neuBtn.type = 'button';
|
||
neuBtn.className = 'btn quiz-neu-btn';
|
||
neuBtn.textContent = '🔄 Neues Quiz starten';
|
||
neuBtn.addEventListener('click', baueQuizAuf);
|
||
screen.appendChild(neuBtn);
|
||
|
||
container.appendChild(screen);
|
||
|
||
// Sanft nach oben scrollen
|
||
container.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||
}
|
||
|
||
/* ═══════════════════════════════════════════════════════════════════════
|
||
Init
|
||
═══════════════════════════════════════════════════════════════════════ */
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
if (!container) return;
|
||
console.log('🧠 Quiz lädt – ' + ALLE_FRAGEN.length + ' Fragen im Pool');
|
||
baueQuizAuf();
|
||
});
|
||
|
||
})();
|