Du hast dein eigenes HTML und CSS geschrieben. Wir haben gesehen, dass man JavaScript benutzen kann um Inhalte auf der Seite zu bewegen. Jetzt lernen wir, wie Programme direkt mit dem HTML geladen werden können, um unsere Seite dynamisch und interaktiv zu machen.
Verstehen, wie eine JavaScript-Umgebung eingerichtet werden kann.
Erstelle in deinem Editor eine Datei mit dem Namen „slideshow.js“ in deinem slideshow-Verzeichnis.
Füge dann in slideshow.js die Zeile hinzu, die die Referenz auf den Film erzeugt:
var filmroll = document.getElementById('the-film-roll');
Binde die neue Datei am Ende von
index.html
ein:
<script src="slideshow.js"></script>
Wechsele in den Browser und lade die Seite neu. Gib folgendes in die Konsole ein:
filmroll.style.left = '-100px';
Halleluja! Ganz wie Bilder und Stylesheets, kann auch JavaScript-Code mit einer gesamten Seite geladen werden. Statt von Hand in die Konsole zu tippen, können wir ein Programm vorbereiten und es zusammen mit HTML, CSS und Bildern schicken.
Die setInterval
-Funktion für eine einfache Funktion
verwenden.
Gestern haben wir gesehen, dass setInterval
benutzt werden kann
um eine Funktion alle x Millisekunden auszuführen. Wir können das
Ausführen der Funktion auch stoppen, indem wir
clearInterval
verwenden. Erweitere
slideshow.js um den folgenden Code und
lade dann die Seite neu:
var filmroll = document.getElementById('the-film-roll'); var start = 0; var end = 200; var current = start; function move() { filmroll.style.left = current + 'px'; current = current + 1; if (current > end) { clearInterval(loop); // This stops the loop } } var loop = setInterval(move, 40);
Warum eignen sich for
- und while
-Schleifen
nicht für diesen Effekt?
Versuch, die Geschwindigkeit der Bewegung zu erhöhen. Es gibt zwei Wege. Welcher funktioniert besser?
Ändere die Funktion move
so, dass sie den Film
alle 50 Millisekunden um 20 Pixel bewegt.
Wie gehst du vor, um eine Bewegung von genau 110 Pixeln zu erzielen? Ändere deine Funktion so, dass sie genau zum Ende (und nicht weiter) läuft.
Tipp: Math.min
ist eine Funktion, die beliebig viele
Zahl-Werte als Parameter annimmt und den kleinsten Wert zurück gibt.
Probier mal das:
current = Math.min(current + 20, end);
Lass sich die Fotos nach links bewegen statt nach rechts.
Um wieviel musst du den Film bewegen um vom ersten Foto zum zweiten zu gehen?
Was passiert wenn die Breite deines Fotos kein Vielfaches von 20 ist? Wie kannst du das Problem umgehen?
Ändere die Funktion move
, so dass die Bewegungsrichtung
nur von den Start- und Endwerten abhängt.
Um zu beeinflussen, wie schnell oder langsam eine Schleife ausgeführt wird, können wir die Zeit zwischen den Aufrufen der Funktion ändern oder ändern, wie groß der Effekt ist den jeder einzelne Aufruf hat.
Wir haben nun immer setInterval
statt einer
while
- oder for
-Schleife benutzt, um die Zeit
zwischen den Aufrufen beeinflussen zu können, statt Tausender kleinster
Veränderungen in Tausenden von Aufrufen zu machen.
Am Ende könnte deine Funktion beispielsweise so aussehen:
function move() { filmroll.style.left = current + 'px'; if (current == end) { clearInterval(loop); } if (end > start) { current = Math.min(current + 20, end); } else { current = Math.max(current - 20, end); } }
Mit den Funktionen Math.min
und Max.max
können wir sicher stellen, dass der Wert von current
nie
den Wert von end
überschreitet. Dabei können wir den Wert
von current
entweder kleiner oder größer halten – je nach
Bewegungsrichtung.
Schreibe eine wiederverwendbare Animations-Funktion die mehrfach ausgeführt werden kann.
Schreibe eine Funktion namens scroll
die eine
Startposition und eine Endposition als Parameter nimmt.
function scroll(start, end) { // und nun? }
Platziere die Zählvariable current
, deine
move
-Funktion und setInterval
in deine neue
Funktion scroll
. Variablen für Start und Ende musst du
nicht mehr definieren. Deine Datei
slideshow.js wird etwa so aussehen:
var filmroll = document.getElementById('the-film-roll'); function scroll(start, end) { var current = start; function move() { filmroll.style.left = current + 'px'; if (current == end) { clearInterval(loop); } if (end > start) { current = Math.min(current + 20, end); } else { current = Math.max(current - 20, end); } } var loop = setInterval(move, 50); }
Lade die Seite im Browser neu.
Benutze nun deine scroll
-Funktion um zum zweiten Foto zu
wechseln. Tippe dazu in die Konsole:
scroll(0, -500);
(… wobei statt 500
die Breite deines Fotos angegeben
wird.)
Benutze die scroll
-Funktion um vom zweiten zum dritten
Foto zu wechseln.
Wechsele zurück zum zweiten Foto.
Nun haben wir eine einzige Funktion, mit der wir von links nach rechts und von jeder Start- zu jeder Endposition wechseln können!
keydown
-Event reagierenHerausfinden, wie wir den Nutzer die Slideshow bedienen lassen können.
Füge in slideshow.js einen
Event Listener namens handleEvent
für das
document
-Objekt hinzu. Der Event Listener ist eine
Funktion, die im Falle eines keydown
-Events ausgeführt
werden soll. Die Funktion „hört“ also sozusagen auf das Ereignis
„Taste runter“:
function handleEvent(e) { console.log(e, e.keyCode); } document.addEventListener('keydown', handleEvent);
Stelle sicher, dass die Developer Tools in Chrome geöffnet sind.
Lade die Seite neu.
Drücke Tasten auf deiner Tastatur und beobachte, was dabei in der Konsole ausgegeben wird.
Was sind die keyCode
s für die linke und rechte
Pfeiltaste?
Erweitere die handleEvent
-Funktion, so dass sie eine
Funktion aufruft, die den Film nach links bzw. rechts bewegt, wenn die
linke oder rechte Pfeiltaste gedrückt wird:
function handleEvent(e) { backAndForth(e.keyCode); } function backAndForth(keyCode) { if (keyCode == 37) { scroll(500, 0); } if (keyCode == 39) { scroll(0, 500); } }
(… wobei statt 500
die Breite deines Fotos angegeben
Teste die neue Funktion im Browser. Denke daran, die Seite immer neu zu laden, wenn du deinen JavaScript-Code im Editor geändert hast.
Warum bewegt es sich nicht weiter in die selbe Richtung, wenn du die selbe Pfeiltaste drückst?
Speichere die aktuelle Position in einer Variable und aktualisiere
den Wert dieser Variable nach dem Aufrufen der
scroll
-Funktion. Benutze die aktuelle Position immer als
den Wert für start
when du die scroll
-Funktion
aufrufst.
Probier es erstmal alleine! Wenn du aber Hilfe brauchst, darfst du hier spicken:
var current = 0; function backAndForth(keyCode) { if (keyCode == 37) { scroll(current, current - 500); current = current - 500; } if (keyCode == 39) { scroll(current, current + 500); current = current + 500; } }
Wenn JavaScript in deinem Browser ausgeführt wird (also immer, außer
es ist abgeschalten), „lauscht“ es durchgehend auf Events, wie
zum Beispiel wenn du tippst oder deine Maus bewegst. Die Events haben
Namen wie „keydown“, „keyup“, and „click“, und werden erzeugt, wenn
irgendeines der entsprechenden Ereignisse eintritt. Sie werden dabei
immer für das Element der Seite erzeugt, an dem sie auftreten, gelten
aber auch für das Dokument insgesamt. Hier interessieren wir uns für die
keydown
-Events, die vom document
ausgehen.
Indem wir auf die Events lauschen, können wir reagieren, wenn die Person vor dem Bildschirm mit der Seite interagiert. Wir können sehen, was getan wurde (was getippt wurde, was geklickt wurde) und dann etwas entsprechendes tun. In diesem Beispiel bewegen wir den Film nach links wenn die Person „links“ drückt, und nach rechts wenn sie „rechts“ drückt.
Durch lauschen auf Eingaben des Besuchers können wir ihm erlauben, die Seite zu steuern.
Damit kann man eine Menge machen!
Lernen, Events zu ignorieren, wenn eine Reaktion unerwünscht wäre.
Unsere Funktionen um auf Events zu lauschen und zu animieren haben einen Fehler, einen Bug. Vielleicht hast du ihn schon bemerkt. Um den Bug hervorzurufen, drücke die linke und rechte Pfeiltaste abwechselnd und schneller als der Film sich bewegen kann. (Drücke also während die Bewegung noch stattfindet wieder „links“ oder „rechts“.) Du wirst ein unschönes Aufblitzen sehen.
Weißt du, was den Fehler verursacht? Wie kannst du ihn verhinden?
Versuche diesen Bug zu fixen.
Wenn wir programmieren, vergessen wir leicht, dass Besucher unserer Seite Dinge tun könnten, die keinen „Sinn“ machen oder die wir nicht vorher gesehen haben. Ohweh. Wir denken zwar, wir hätten unsere Arbeit getan, aber wenn wir herausfinden, dass unser Code einen Bug hat, müssen wir ihn beheben (oder den Nutzern sagen „Lass das!“, was sehr unhöflich ist.)
Erstmal müssen wir bemerken, dass der Bug existiert. Dann müssen wir herausfinden, warum er existiert. Dann müssen wir herausfinden, wie wir ihn beseitigen können. Viele Programmierer haben Spaß am Aufspüren von Bugs, weil sie ein spannendes Puzzle sind.
Hast du eine Lösung gefunden? Hier ist ein Vorschlag dafür:
var scrolling = false; function scroll(start, end) { var current = start; var move = function () { filmroll.style.left = current + 'px'; if (current == end) { clearInterval(loop); scrolling = false; } if (end > start) { current = Math.min(current + 20, end); } else { current = Math.max(current - 20, end); } } var loop = setInterval(move, 50); scrolling = true; } function handleEvent(e) { if (!scrolling) { backAndForth(e.keyCode); } }
Wir haben eine Variable erzeugt in der wir uns merken ob sich der
Film gerade bewegt. Falls er das tut, können wir das
keydown
-Event ignorieren wenn es eintritt.
Diese Lösung verwendet ein Ausrufungszeichen in der
if (!scrolling)
-Bedingung (in der Funktion
handleEvent
). Das Ausrufungszeichen nennt man den
logischen NOT-Operator in JavaScript (also „nicht“, eine Verneinung).
Die Bedingung if (!scrolling)
bedeutet also: falls die Variable
scrolling
nicht true (wahr) ist.
Vielleicht passt diese Lösung aber gar nicht zu dem, was der Nutzer erwartet. Was würde der Nutzer hier wohl vernünftiger Weise erwarten? Wie können wir den Code so ändern, dass er sich so verhält, wie man erwarten würde?
Jetzt wo wir Änderungen am CSS gemacht haben, wollen wir auch das HTML verändern!