Beispiel:Mathe-Quiz-fertig.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>Mathe-Quiz</title>
<style>
.toggle-buttons input[type="radio"] {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
.toggle-buttons label {
display: inline-block;
border: 1px solid #333;
border-radius: 0.5em;
width: 2rem;
height: 2rem;
margin: 0.5rem;
font: 0/0;
color: transparent;
}
/* Original-SVG-Grafiken in img/mathe-quiz-labels.svg */
.toggle-buttons label[for=add] {
background-image: url("data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%20%20%3Cstyle%3E%0A%20%20%20path%20%7B%0A%09%20%20%20stroke%3A%20black%3B%0A%09%20%20%20stroke-width%3A%202.5px%3B%0A%09%20%20%20stroke-linecap%3A%20round%3B%0A%20%20%20%7D%0A%20%20%20%3C/style%3E%0A%20%20%20%3Cpath%20d%3D%22M6%2C12%20h12%20M12%2C6%20v12%22/%3E%0A%3C/svg%3E");
}
.toggle-buttons label[for=subtract] {
background-image: url("data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%20%20%3Cstyle%3E%0A%20%20%20path%20%7B%0A%09%20%20%20stroke%3A%20black%3B%0A%09%20%20%20stroke-width%3A%203px%3B%0A%09%20%20%20stroke-linecap%3A%20round%3B%0A%20%20%20%7D%0A%20%20%20%3C/style%3E%0A%20%20%20%3Cpath%20d%3D%22M6%2C12%20h12%22/%3E%0A%3C/svg%3E");
}
.toggle-buttons label[for=divide] {
background-image: url("data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%20%20%3Cstyle%3E%0A%20%20%20path%20%7B%0A%09%20%20%20stroke%3A%20black%3B%0A%09%20%20%20stroke-width%3A%203px%3B%0A%09%20%20%20stroke-linecap%3A%20round%3B%0A%20%20%20%7D%0A%20%20%20%3C/style%3E%0A%20%20%20%3Cpath%20d%3D%22M6%2C12%20h12%22/%3E%0A%20%20%20%3Ccircle%20cx%3D%2212%22%20cy%3D%226%22%20r%3D%221.5%22%20/%3E%0A%20%20%20%3Ccircle%20cx%3D%2212%22%20cy%3D%2218%22%20r%3D%221.5%22%20/%3E%20%20%20%0A%3C/svg%3E");
}
.toggle-buttons label[for=multiply] {
background-image: url("data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%20%20%3Cstyle%3E%0A%20%20%20path%20%7B%0A%09%20%20%20stroke%3A%20black%3B%0A%09%20%20%20stroke-width%3A%203px%3B%0A%09%20%20%20stroke-linecap%3A%20round%3B%0A%20%20%20%7D%0A%20%20%20%3C/style%3E%0A%20%20%20%3Cpath%20d%3D%22M9%2C9%20l6%2C6%20M15%2C9%20l-6%2C6%22/%3E%0A%3C/svg%3E");
}
.toggle-buttons label[for=any] {
background-image: url("data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2048%2048%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%20%20%3Cstyle%3E%0A%20%20%20path%20%7B%0A%09%20%20%20stroke%3A%20black%3B%0A%09%20%20%20stroke-width%3A%203px%3B%0A%09%20%20%20stroke-linecap%3A%20round%3B%0A%20%20%20%7D%0A%20%20%20%3C/style%3E%0A%20%20%20%3Cpath%20id%3D%22plus%22%20d%3D%22M6%2C12%20h12%20M12%2C6%20v12%22/%3E%0A%20%20%20%3Cpath%20id%3D%22minus%22%20d%3D%22M30%2C12%20h12%22/%3E%0A%20%20%20%3Cpath%20id%3D%22divide%22%20d%3D%22M6%2C36%20h12%22/%3E%0A%20%20%20%3Ccircle%20cx%3D%2212%22%20cy%3D%2230%22%20r%3D%221.5%22%20/%3E%0A%20%20%20%3Ccircle%20cx%3D%2212%22%20cy%3D%2242%22%20r%3D%221.5%22%20/%3E%20%20%20%0A%20%20%20%3Cpath%20id%3D%22multiply%22%20transform%3D%22translate%2824%2C24%29%22%20d%3D%22M9%2C9%20l6%2C6%20M15%2C9%20l-6%2C6%22/%3E%0A%3C/svg%3E");
}
.toggle-buttons label[for=open-dialog] {
margin: 1em 0 0 0;
}
.toggle-buttons input:checked + label {
background-color: #ebf5d7;
}
#task {
font-size: 2em;
margin: 2em auto;
}
#task span {
display: inline-block;
width: 1em;
text-align: center;
}
/* Scrollleiste von type="number" wird ausgeblendet */
#task input[type="number"]{
width: 2em;
-moz-appearance: textfield;
appearance: textfield;
margin: 0;
font-size: 1em;
}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
#task button {
font-size: 1.33em;
padding: -0.5em 0 0;
height: 1em;
width: 1em;
line-height: 90%;
vertical-align: top;
}
output {
display: block;
margin: 2em 0;
}
.exact {
font-weight: bold;
color: green;
}
output.exact:after {
content: "✓";
display: block;
margin: 0.8em 0 0 1em;
}
.inexact {
font-weight: bold;
color: red;
}
output.inexact:after {
content: "✗";
display: block;
margin: 0.8em 0 0 1em;
}
[for=input] {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
</style>
<script>
'use strict';
document.addEventListener("DOMContentLoaded", function () {
let input = document.getElementById('input'),
output = document.querySelector('output'),
randomNumberMax = 10,
result = 0,
stat = {
correct: 0,
incorrect: 0
};
function createGame () {
document.querySelector('#rechenarten').addEventListener('change', createTask);
// Beim Verlassen der Seite wird vorher die Statistik gespeichert
window.addEventListener('beforeunload', function(event) {
localStorage.setItem('item', JSON.stringify(stat));
});
// gespeicherte Statistik laden. Wenn keine vorhanden, Info-Template laden
getStorage();
// Button um Statistiken zurückzusetzen
document.querySelector('#reset-stat').addEventListener('click', resetStatistics);
// submit-Button einrichten
document.querySelector('#task').addEventListener('submit', evaluateResponse);
createTask();
}
function createTask () {
var a,
b;
/* In diesem Objekt sind für jeden Operator sowohl die Symbole als auch die Rechenoperation gespeichert.
Für den Zufallsoperator werden die Operatoren dann mit der Zufallsfunktion ausgesucht.
Die Zufallszahlen je nach Operator so ermitteln, dass als Ergebnis nur positive Ganze Zahlen herauskommen.
*/
var opMap = {
"+": function() {
a = rand( 1, randomNumberMax * 3);
b = rand( 1, randomNumberMax * 3);
result = a+b;
return "+";
},
"-": function() {
// So kann sichergestellt werden, dass das Ergebnis immer positiv ist
b = rand( 1, randomNumberMax * 3);
a = rand( b, randomNumberMax * 3);
result = a-b;
return "-";
},
"×": function() {
a = rand( 1, randomNumberMax);
b = rand( 1, randomNumberMax);
result = a*b;
return "×";
},
"÷": function() {
// So kann sichergestellt werden, dass das Ergebnis immer eine ganze Zahl ist
b = rand( 1, randomNumberMax);
a = b * rand( 0, randomNumberMax);
result = a/b;
return "÷";
},
"any": function() {
var p, props = [];
for (p in opMap) {
if (p != "any") {
props.push(p);
}
}
p = rand(0, props.length);
return opMap[props[p]]();
}
};
// vorherige Eingaben werden entfernt
output.textContent = 'Bitte gib das Ergebnis ein!';
output.className = '';
document.getElementById('input').value = '';
/* Rechnung durchführen, Zufallszahlen dabei ermitteln und
Operator-Symbol ins Dokument ausgeben */
document.querySelector('#operator').textContent = opMap[
document.querySelector('input[name="op"]:checked').getAttribute(
"data-operator"
)
]();
// Zufallszahlen in task ausgeben
document.querySelector('#var1').textContent = a;
document.querySelector('#var2').textContent = b;
}
function evaluateResponse (evt) {
// Ergebnis mit Eingabe vergleichen
evt.preventDefault();
if (result == input.value){
output.textContent = 'Super!';
output.className = 'exact';
stat.correct++;
} else {
output.textContent = 'Leider falsch!';
output.className = 'inexact';
stat.incorrect++;
}
setTimeout(createTask, 1000);
}
// Statistiken aus LocalStorage holen
function getStorage () {
var eintraegeArray = localStorage.getItem('item');
if (eintraegeArray) {
output.innerText = eintraegeArray;
stat = JSON.parse(eintraegeArray);
}
else {
output.textContent = 'Herzlich willkommen in unserem Mathe-Quiz! Gib das Ergebnis der Rechnung ein und drücke die Enter-Taste!';
}
return stat;
}
// Statistiken zurücksetzen
function resetStatistics () {
stat.correct = 0;
stat.incorrect = 0;
getStatistics();
document.querySelector('#ergebnis').textContent = 'Statisiken wurden zurückgesetzt!';
}
// Statistiken ausgeben
function getStatistics () {
document.querySelector('#richtig').textContent = stat.correct;
document.querySelector('#falsch').textContent = stat.incorrect;
var percentage = stat.correct/( stat.correct+stat.incorrect)*100;
document.querySelector('#prozent').textContent = percentage.toFixed(2);
}
// erzeugt Zufallszahl
function rand (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
//Polyfill für dialog-Element
document.querySelector('#open-dialog').addEventListener('click', getStatisticsDialog);
function getStatisticsDialog (){
getStatistics ();
toggleDialog ();
}
function toggleDialog (){
var dialog = document.querySelector('dialog'),
closeButton= document.getElementById('close-dialog');
if (!dialog.hasAttribute('open')) {
// show the dialog
dialog.setAttribute('open','open');
// after displaying the dialog, focus the closeButton inside it
closeButton.focus();
closeButton.addEventListener('click', toggleDialog);
// EventListener für ESC-Taste
document.addEventListener('keydown', function(event) {
if (event.keyCode == 27) {
toggleDialog();
}
}, true);
// only hide the background *after* you've moved focus out of the content that will be "hidden"
var div = document.createElement('div');
div.id = 'backdrop';
document.body.appendChild(div);
}
else {
dialog.removeAttribute('open');
var div = document.querySelector('#backdrop');
div.parentNode.removeChild(div);
lastFocus.focus();
}
}
createGame ();
});
</script>
</head>
<body>
<h1>Mathe-Quiz</h1>
<form class="toggle-buttons" id="rechenarten">
<input type="radio" name="op" data-operator="+" id="add" checked><label for="add">+</label>
<input type="radio" name="op" data-operator="-" id="subtract"> <label for="subtract">-</label>
<input type="radio" name="op" data-operator="÷" id="divide"> <label for="divide">/</label>
<input type="radio" name="op" data-operator="×" id="multiply"> <label for="multiply">x</label>
<input type="radio" name="op" data-operator="any" id="any"> <label for="any" title="Zufallsauswahl">?</label>
</form>
<form id="task">
<span id="var1">a</span>
<span id="operator">+</span>
<span id="var2">b</span>
=
<label for="input">Ergebnis eingeben:</label>
<input id="input" type="number" step="1" size="3">
<button type="submit" aria-label="Berechnung starten">↵</button>
</form>
<p><output>Ergebnisausgabe</output></p>
<button id="open-dialog">Ergebnisse und Statistiken</button>
<dialog role="dialog">
<button id="close-dialog">X</button>
<h2>Ergebnis</h2>
<p>Richtig: <span class="exact" id="richtig"></span></p>
<p>Falsch: <span class="inexact" id="falsch"></span></p>
<p>Prozent: <span id="prozent"></span>%</p>
<button id="reset-stat">Statistiken zurücksetzen</button>
<p id="ergebnis"></p>
</dialog>
</body>
</html>