Herzlich willkommen zum SELF-Treffen 2026
vom 24.04. – 26.04.2026
in Halle (Saale)
Beispiel:JS-DOM-Tut-15.html
<!DOCTYPE html> <html lang="de"> <head> <meta charset="utf-8"> <title>Sum-up (Zerlegen von Zahlen)</title> <meta name="viewport" content="width=device-width, initial-scale=1.0;"> <link rel="stylesheet" media="screen" href="./Beispiel:Grundlayout.css" /> <style>
- game {
color: white; overflow: hidden; display: block; margin: 0 auto; }
- display {
background: #333; border: thin solid #006; border-radius: 10%; float: right; font-size: 5em; height: 1.3em; margin: 0; padding: 0.5em; text-align: center; width: 1.3em; } @media (width < 40em) {
#wrapper {
padding: 1em;
height: 12em;
}
}
- feedback {
background: white; box-shadow: 0 0 .5em white; color: black; }
- restart-button {
display: none; }
.game-over #wrapper { display: none; }
.game-over #restart-button { display: block; margin-bottom: 1em; }
- game span {
display: inline-block; float: left; width: 3.5em; }
.exact { font-weight: bold; color: lime; }
.exact:after { content: "✓"; display: block; margin: -0.5em 0 0 1em; }
.inexact { font-weight: bold; color:red; }
.inexact:after { content: "✗"; display: block; margin: -0.5em 0 0 1em; }
button[class^="type"] { background-color: #FFF; border: thin solid #006; border-radius: 30%; color: #000; float: left; font-size: 120%; font-weight: bold; height: 2.7em; width: 2.7em; margin: 0 .3em .3em 0; padding: 0.25em 0; text-align: center; }
- not(.game-over) [class^="type"] {
cursor: pointer; }
button.type1 {background: red; } button.type2 {background: orange;} button.type3 {background: yellow;} button.type4 {background: lime;} button.type5 {background: skyblue;} button.type6 {background: blue; color: white;} button.type7 {background: purple; color: white} button.type8 {background: maroon; color: white;} button.type9 {background: darkgreen; color: white;}
body {
width: 45em !important; max-width: 90% !important; margin: 0 auto;
} </style> <script> 'use strict'; document.addEventListener("DOMContentLoaded", function () {
const container = document.getElementById("game"), // Liste aller Klickbuttons mit Zahlen buttons = [], // Wrapper für schmale Bildschirme wrapper = document.createElement("div"), // Zielzahl-Anzeige display = document.createElement("p"), // Liste aller Zufallszahlen numbers = [], // Restart-Button restart = document.createElement("button"), // 12 Zufallszahlen zu meistern size = 12;
// Veränderliche Zustandsvariablen let current = 0, clicks = 0, getroffen = 0, index = 0;
/** * Handler-Funktion für click/tap * * Diese Funktion wertet die angeklickten Zahlen aus und reagiert * auch auf den Restart-Button. * * @param Event */ function click (e) {
if (e.target == restart) { return start(); }
// buttons nur auswerten wenn das Spiel gestartet wurde if (container.classList.contains("game-over") || current <= 0 ) { return; }
buttons.forEach(function (b) {
if (e.target == b) {
// Klick zählen clicks++;
// Zwischensumme aktualisieren current -= +b.textContent;
// Button entfernen b.remove();
if (current <= 0) {
if (current === 0) { getroffen++; }
display.className = ( current === 0 ? "exact" : "inexact" );
setTimeout(next, 1500); } } });
e.preventDefault(); e.stopPropagation(); }
/** * Funktion zum Beenden des Spiels */ function end () { const anteil = Math.round(getroffen / size * 100), p = container.appendChild(document.createElement("p"));
p.textContent = "Du hast mit " + clicks + " Klicks von " + size + " Zielzahlen " + getroffen + " getroffen, das sind " + anteil + " Prozent."; p.id = "feedback";
container.className = "game-over"; }
/** * Funktion für neue/weitere Zielzahl * * Diese Funktion prüft, ob das Spiel weitergehen könnte * und leitet nötigenfalls zu end() weiter. */ function next () { let r = 0; // Restwert aller übrigen Buttons
document.querySelectorAll('button[class^="type"]').forEach( function (b) { r += +b.textContent; } );
index--;
if (index < 0 // letzte Zahl erreicht? // kann die aktuelle Zahl überhaupt noch erreicht werden? || r < numbers[index] ) { return end(); }
current = numbers[index]; display.textContent = current; display.className = ""; }
/** * Helfer-Funktion für Integer-Zufallszahlen * * @param int Minimum * @param int Maximum * @return int Zufallszahl */ function rand (min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
/** * Funktion zum Mischen eines Arrays (Fisher-Yates) * * http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array#answer-25984542 * * @param Array input * @return Array shuffled */ function shuffle (array) { let count = array.length, r, temp;
while (count) { r = Math.random() * count-- | 0; temp = array[count]; array[count] = array[r]; array[r] = temp; }
return array; }
/** * Funktion zum (erneuten) Starten des Spiels * * Diese Funktion bereitet alle notwendigen Elemente so vor, dass * das Spiel begonnen werden kann. */ function start () { const max = Math.floor(Math.sqrt(size * 3)); let s;
// Zähler zurücksetzen clicks = 0; getroffen = 0;
// container leeren - bis auf display (im wrapper) und restart while (container.lastChild != wrapper && container.lastChild != restart ) { container.lastChild.remove(); }
// Zufallszahlen vermischen shuffle(numbers); index = numbers.length; // Zeiger hoch setzen
// Klickzahlen vermischen shuffle(buttons);
// Klickzahlen in das Spielfeld bringen buttons.forEach(function (b, i) {
if (i % max === 0) { s = container.appendChild(document.createElement("span")); }
s.appendChild(b); });
container.classList.remove("game-over");
next(); }
/** * Setup-Funktion * * Jetzt werden alle benötigten Elemente gebaut und für start() * vorbereitet. */ (function () {
// Zufallszahlen erstellen und speichern for (let i = 0; i < size; i++) {
const r = rand(10, 19);
numbers.push(r);
// jede Zufallszahl wird in drei kleinere Zahlen aufgeteilt const z1 = rand(3, Math.floor(r / 2)); const z2 = rand(1, 4);
[z1, z2, r - z1 - z2].forEach(function (z) { const b = document.createElement("button");
b.textContent = z;
// zufällige Färbung b.className = "type" + rand(1, 9);
// passenden Button speichern buttons.push(b); }); }
// Display und Restart-Button vorbereiten display.id = "display"; restart.id = "restart-button"; restart.textContent = "Spiel starten";
// container leeren und click-Listener installieren container.replaceChildren(); container.addEventListener("click", click);
// wrapper in den container wrapper.id = "wrapper"; container.appendChild(wrapper);
// display in den wrapper wrapper.appendChild(display);
// restart-button in container einhängen container.appendChild(restart);
// container mit "Ende"-Markierung versehen container.classList.add("game-over"); }());
}); </script> </head> <body>
Sum-up - das lustige Rechenspiel
<main>
Drücke solange auf die Zahlen, bis du auf die Summe rechts oben kommst!
</main> </body> </html>