Der bewegte Käfer: Eine JavaScript- & jQuery-Spielerei mit grossem Lerneffekt in 3 Versionen
Alex Kereszturi zeigt im Blog, wie man mit JavaScript, JSON und Variablen dynamische Webapplikationen, in diesem Fall ein simples Käferspiel, erstellen kann.
Wer schon etwas Erfahrung im Schreiben von JavaScript-Anwendungen gesammelt hat, weiss: viele Wege führen nach «Rom». Gerne zeige ich in JavaScript-Kursen wie z.B. dem Kurs: JavaScript-Programmierung («ISC») gerne möglichst viele dieser Wege auf, weil man beim Beschreiten solcher Wege sehr viel lernen kann, auch wenn man dann in der Praxis vielleicht nur einen davon nimmt.
In diesem Blogbeitrag möchte ich gerne so eine «Rom-Reise» mit allen antreten, die sich etwas vertieft mit JavaScript auseinandersetzen möchten.
Worum es (mir als Autor) geht
Häufig müssen in JavaScript immer wieder dieselben Funktionalitäten umgesetzt werden, einfach mit anderen Parametern. Vergleichbar mit einer Waschmaschine, die ja nichts anderes macht, als meine Wäsche zu waschen – einfach immer wieder mit unterschiedlichen Waschprogrammen. Wie bringt man nun aber so einer JavaScript-Waschmaschine bei, dass sie einmal mit 60 Grad und einmal mit 40 Grad waschen soll? Wie sag ich meiner Maschine, dass sie einmal mit und einmal ohne Vorwäsche arbeiten soll?
Wer sich mit JavaScript – oder mit dem Programmieren allgemein – schon etwas auskennt, wird jetzt postwendend sagen: «Mit Funktionen, denen man Parameter übergibt.»
Richtig!
Die Frage stellt sich nur, woher diese Parameter kommen bzw. wo, wann und wie sie übergeben werden.
Die Ausgangslage
Damit es verständlicher wird, worauf ich hinaus will, hier erst einmal das Setup und die Problemstellung.
Beginnen wir mit einer (ganz normalen) HTML-Datei, in der sich folgender Code im BODY-Tag befindet:
<div id="myBug">KÄFER</div>
<button>NACH RECHTS</button>
<button>NACH LINKS</button>
Wie es die Beschriftung bereits vermuten lässt, soll sich das DIV mit dem Text «Käfer» nach links bzw. nach rechts bewegen, wenn man die entsprechenden Buttons klickt.
Weg 1: Die «Holzhammer»-Methode
Der (auf Anhieb) einfachste Weg scheint wohl jener zu sein, der den einzelnen Buttons entsprechende Event-Handler zuordnet. Ein SCRIPT-Tag vor dem schliessenden BODY-Tag würde entsprechend in etwa diesen Code beinhalten:
var myBug = document.getElementById("myBug");
myBug.style.position = "absolute";
myBug.style.top = "100px";
myBug.style.left = "100px";
document.getElementsByTagName("button")0.onclick = function() {
myBug.style.left = (Number(myBug.style.left.replace(/px/g,""))+10)+"px";
}
document.getElementsByTagName("button")1.onclick = function() {
myBug.style.left = (Number(myBug.style.left.replace(/px/g,""))-10)+"px";
}
Was wir schleunigst mit ein bisschen jQuery-Zauberei (also bitte jQuery einbinden) zu Folgendem vereinfachen – auch damit es verständlicher wird:
var myBug = $("#myBug");
myBug.css({
position: "absolute",
top: "100px",
left: "100px"
});
document.getElementsByTagName("button")0.onclick = function() {
myBug.css("left", "+=10");
}
document.getElementsByTagName("button")1.onclick = function() {
myBug.css("left", "+=-10");;
}
Funktioniert soweit gut. Was aber nicht so gefällt, ist die Tatsache, dass für jeden Button der Event-Handler für onclick einzeln definiert werden muss, da ja jeder Button seine eigene Bewegung (einmal nach rechts und einmal nach links) umsetzen muss. Zudem würde jetzt alles über den Haufen geworfen werden, würde ich im HTML die Reihenfolge der Buttons ändern.
In Kursen formuliere ich an diesem Punkt die nächste Aufgabe folgendermassen: Man löse die Event-Handler-Zuweisung mit einer Iteration.
Weg 2: Der Button selbst kennt die Parameter
Setzen wir erst einmal die Iteration um. Dank jQuery ein Kinderspiel:
$("button").click(function(){
myBug.css("left", "+=10");
});
Schon hat – dank der impliziten Iteration von jQuery – jeder Button einen Event-Handler für den Klick-Event.
Wenn Sie sich jetzt fragen, was um Himmels Willen eine implizite Iteration ist, könnte dieser Blogbeitrag von mir oder ein starker Kaffee vielleicht helfen.
Aber zurück zu unserem Käferspiel.
Zwar hat jetzt jeder Button einen Event-Handler, aber alle «machen» dasselbe. Der Käfer bewegt sich immer in dieselbe Richtung, egal welchen Button man klickt. Die Frage stellt sich also, wie kann ich trotz Iteration unterschiedliche Parameter verwenden?
Da die einzelnen HTML-Buttons durchiteriert werden, müsste man die Parameter in die Buttons packen können. Nur wie?
HTML5 hilft! Seit HTML5 können HTML-Elemente nämlich selbstdefinierte Parameter enthalten. Wenn diese mit dem Präfix “data-” beginnen, werden sie sogar vom http://validator.w3.org unbemängelt angenommen.
Wenn wir also den HTML-Teil unseres Codes folgendermassen anpassen …
<button data-move="10">NACH RECHTS</button>
<button data-move="-10">NACH LINKS</button>
… und die Funktion in der Iteration folgendermassen ergänzen …
$("button").click(function(){
var myMove = $(this).attr("data-move");
myBug.css("left", "+=" + myMove);
});
… bewegt sich der Käfer wieder nach Wunsch einmal nach links und einmal nach rechts.
Weg 3: JSON, ahoi!
Soweit so gut, was aber, wenn ich jetzt einen Button haben möchte, der den Käfer nach unten bewegt? Sich also nicht nur der Wert des Parameters ändert, sondern auch die CSS-Eigenschaft, der der Wert zugeordnet werden soll?
Statt dem HTML-Element nun unzählige unterschiedliche Parameter zu verpassen oder im JavaScript mit verschachtelten und unübersichtlichen IF-Konstrukten zu arbeiten, könnten wir uns auch einfach die Tatsache zu nutze machen, dass jQuery sehr gerne mit JSON arbeitet. Warum also nicht die (komplette) JSON-Konfiguration für das Ändern der CSS-Eigenschaften im HTML-Element abspeichern?
<button data-move="{'left':'+=10'}">NACH RECHTS</button>
<button data-move="{'left':'+=-10'}">NACH LINKS</button>
<button data-move="{'top':'+=10'}">NACH UNTEN</button>
Wenn wir unsere Iteration noch wie folgt anpassen, könnte es klappen:
$("button").click(function(){
var myMove = $(this).attr("data-move");
myBug.css(myMove);
});
Leider passiert so im Browser gar nichts! Wir holen zwar in die Variable myMove den Wert des Attributs data-move und dieser Wert ist auch ein JSON-String, aber leider ist es (noch immer) ein String und wird von JavaScript (noch nicht) als Objekt gewertet. Dies kann man sehr schön mittels einer Ausgabe vom Typ von myMove in der Konsole sehen:
var myMove = $(this).attr("data-move");
console.log(typeof myMove);
Wir sehen in der Konsole «string», hätten dort aber gerne ein «object». Um dies zu erreichen, brauchen wir zwei kleine «Kniffe». Erstens passen wir den «data-move»-Parameter unserer Buttons wie folgt an:
data-move="({'left':'+=10'})"
Die Klammern um den JSON-String bewirken – wie in der Mathematik – vorerst einmal nichts. Erst wenn wir bei der Zuweisung des Parameterwerts an die Variable myMove noch ein eval() einbauen, wird es spannend:
var myMove = eval( $(this).attr("data-move") );
console.log(typeof myMove);
Mittels eval() weisen wir JavaScript an, den String auszuwerten, wie wenn es ein JavaScript-Befehl wäre. Die einfachen Klammern «zwingen» JavaScript jetzt dazu – wie in der Mathematik – erst den Begriff in Klammern (also den JSON-String) «auszuführen», bevor er der Variablen zugewiesen wird.
In der Konsole erhalten wir jetzt wie gewünscht ein «object».
Und: Das Spiel funktioniert!
Der gesamte Code im Überblick
<div id="myBug">KÄFER</div>
<button data-move="({'left':'+=10'})">NACH RECHTS</button>
<button data-move="({'left':'+=-10'})">NACH LINKS</button>
<button data-move="({'top':'+=10'})">NACH UNTEN</button>
<script>
var myBug = $("#myBug");
myBug.css({
position: "absolute",
top: "100px",
left: "100px"
});
$("button").click(function(){
myMove = eval( $(this).attr("data-move") );
console.log(typeof myMove);
myBug.css(myMove);
});
</script>
Abschliessendes
Wenn Sie jetzt vor lauter JSON und Variablen-Zuweisungen das JavaScript nicht mehr sehen, freue ich mich jetzt schon, Sie in einem meiner JavaScript- oder jQuery-Kurse (z.B. Kurs: JavaScript-Programmierung («ISC») oder Kurs: Gestaltung dynamischer Webapplikationen mit jQuery («IJQ»)) begrüssen zu dürfen.
Wenn Sie Spass an dieser kleinen «Reise nach Rom» hatten, werden Sie es lieben, Ihre Gehirnzellen im Kurs Kurs: JavaScript für Softwareentwickler («JSFSEN») weiter kitzeln zu lassen.
JavaScript-Kurse bei DigicompEntdecken Sie unser breites Angebot für den Einstieg in Programmiersprachen. Zum Beispiel: |
Entdecken Sie unser breites Angebot für den Einstieg in Programmiersprachen. Zum Beispiel: