Beispiel:2025-Quiz.html
Aus SELFHTML-Wiki
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" media="screen" href="./Beispiel:SELFHTML-Beispiel-Grundlayout.css">
<title>Multiple-Choice-Quiz - 2025</title>
<style>
#quiz label {
display: block;
background-color: lightBlue;
border: medium solid steelBlue;
cursor: pointer;
transition: background-color 0.2s, border-color 0.2s;
}
/* Hover-Effekt */
#quiz label:hover {
background-color: lightyellow;
}
/* mache Fokus sichtbar */
#quiz input[type="radio"]:focus + label {
outline: 2px solid black;
outline-offset: 2px;
}
/* Auswahl */
#quiz input[type="radio"]:checked + label {
background-color: gold;
border-color: #866a00;
}
#quiz input { /*visually-hidden */
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
#quiz label {
border-radius: 0.2em;
margin: 0.1em 0;
padding: 1em 2em;
max-width: 33em;
}
#quiz legend {
border: thin solid;
border-radius: 0 0.5em 0.5em;
padding: 0.5em;
}
#quiz button{
padding: 0.5em;
font-size: 1.1em;
}
/* listing with solutions */
.question {
font-weight: bold;
}
.correct {
color: #0c0;
}
.incorrect {
color: #c00;
}
.correct:before {
content: '✓';
color: #0d0;
}
.incorrect:before {
content: '✗';
color: #f00;
}
.correct:before,
.incorrect:before {
font: 2em bold;
padding: 0 0.2em;
}
#scores,
#scores td,
#scores th {
border: 1px solid black;
border-collapse: collapse;
text-align: center;
}
</style>
</head>
<body><h1>Multiple-Choice-Quiz zum Jubiläum</h1>
<form id="quiz">
<p id="intro"><img src="https://wiki.selfhtml.org/images/a/a9/Mannheim_Quadratstadt.svg" alt="vereinfachte Darstellung der Quadratestadt Mannheim Mit alten und neuen SELF-Logos" width=300" style="float:right;margin-left:1em"> Zum 10-Jährigen Jubiläum gab es 2005 ein Quiz, 2016 ein Self-Weihnachtsquiz. <br>Es hat lange gedauert, aber zum 30-Jährigen Jubiläum liefern wir eine Neuauflage!</p>
<button type="submit">Starte Quiz!</button>
</form>
<template id="quizRadiogroup">
<fieldset role="radiogroup">
<legend>Frage …</legend>
</fieldset>
</template>
<script>
document.addEventListener("DOMContentLoaded", function () {
const JSONUrl = "/extensions/Selfhtml/example.php/Beispiel:2025.json";
const form = document.getElementById("quiz");
const intro = document.getElementById("intro");
const button = form.querySelector("button");
const template = document.getElementById("quizRadiogroup");
let questions = [];
let currentQuestionIndex = 0;
let results = [];
button.addEventListener("click", async function (e) {
e.preventDefault();
if (document.getElementById("intro")) {
document.getElementById("intro").remove();
await loadQuestions();
renderQuestion(currentQuestionIndex);
button.textContent = "Auswahl bestätigen";
} else {
handleSubmit();
}
});
async function loadQuestions() {
try {
const response = await fetch(JSONUrl);
const data = await response.json();
questions = data.data;
} catch (error) {
console.error("Fehler beim Laden der Fragen:", error);
}
}
function renderQuestion(index) {
const questionData = questions[index];
const oldFieldset = form.querySelector("fieldset");
if (oldFieldset) oldFieldset.remove();
const quizContent = template.content.cloneNode(true);
const fieldset = quizContent.querySelector("fieldset");
const legend = fieldset.querySelector("legend");
legend.innerHTML = `${questionData.category}: ${questionData.question}`; //to allow code and pre
// Clear all children except the legend element
while (fieldset.children.length > 1) {
fieldset.removeChild(fieldset.lastChild);
}
questionData.answers.forEach((answer, i) => {
const inputId = `q${index}_a${i}`;
const input = document.createElement("input");
input.type = "radio";
input.name = `q${index}`;
input.id = inputId;
input.value = answer.answer;
const label = document.createElement("label");
label.htmlFor = inputId;
label.textContent = answer.answer;
fieldset.appendChild(input);
fieldset.appendChild(label);
});
form.insertBefore(fieldset, button);
}
function handleSubmit() {
const selected = form.querySelector(`input[name="q${currentQuestionIndex}"]:checked`);
if (!selected) {
alertBox("Bitte wählen Sie eine Antwort aus!", "error");
return;
}
const question = questions[currentQuestionIndex];
const selectedValue = selected.value;
const selectedAnswerObj = question.answers.find(a => a.answer === selectedValue);
const correctAnswer = question.answers.find(a => a.correct);
const isCorrect = selectedAnswerObj?.correct;
// Store result
results.push({
question: question.question,
userAnswer: selectedValue,
isCorrect,
correctAnswer: correctAnswer.answer,
explanation: question.explanation || "",
});
currentQuestionIndex++;
if (currentQuestionIndex < questions.length) {
setTimeout(() => {
renderQuestion(currentQuestionIndex);
}, 500);
} else {
form.remove(); // remove quiz form
renderResults();
}
}
function renderResults() {
const resultList = document.createElement("ol");
resultList.id = "result";
results.forEach(result => {
const li = document.createElement("li");
const questionP = document.createElement("p");
questionP.className = "question";
questionP.innerHTML = result.question;
const answerP = document.createElement("p");
answerP.innerHTML = `Ihre Antwort: <em class="${result.isCorrect ? "correct" : "incorrect"}">${result.userAnswer}</em>`;
const explanationP = document.createElement("p");
explanationP.innerHTML = `Erläuterung: <em>${result.explanation}</em>`;
li.appendChild(questionP);
li.appendChild(answerP);
li.appendChild(explanationP);
resultList.appendChild(li);
});
const score = results.filter(r => r.isCorrect).length;
const total = results.length;
const scoreSummary = document.createElement("p");
const percentage = Math.round((score / total) * 100);
scoreSummary.innerHTML = `<strong>Ergebnis:</strong> ${score} von ${total} Fragen richtig beantwortet (${percentage}%).`;
document.body.appendChild(scoreSummary);
document.body.appendChild(resultList);
}
function alertBox(text, type) {
const alert = document.createElement("p");
alert.textContent = text;
alert.className = type;
form.appendChild(alert);
setTimeout(() => alert.remove(), 3000);
}
});
</script>
</body>
</html>