-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathpage3_de.html
429 lines (310 loc) · 12.6 KB
/
page3_de.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
<!doctype html>
<head>
<title>Kursmaterial — Seite 3</title>
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Averia+Serif+Libre:300,400">
<link rel="stylesheet" href="style.css">
<meta charset="utf-8">
</head>
<h1>Kursmaterial: Seite 3, Bewegte Bilder</h1>
<p>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.</p>
<h2 class="step">Eine JavaScript-Datei einbinden</h2>
<h3 class=goal>Ziel</h3>
<p>Verstehen, wie eine JavaScript-Umgebung eingerichtet werden kann.</p>
<h3 class=inst>Anweisungen</h3>
<p>Erstelle in deinem Editor eine Datei mit dem Namen „slideshow.js“
in deinem <span class="filename">slideshow</span>-Verzeichnis.</p>
<p>Füge dann in <span class="filename">slideshow.js</span> die Zeile
hinzu, die die Referenz auf den Film erzeugt:</p>
<pre>
var filmroll = document.getElementById('the-film-roll');
</pre>
<p>Binde die neue Datei am <strong>Ende</strong> von
<code>index.html</code> ein:</p>
<pre>
<script src="slideshow.js"></script>
</pre>
<p>Wechsele in den Browser und lade die Seite neu. Gib folgendes in die
Konsole ein:</p>
<pre>
filmroll.style.left = '-100px';
</pre>
<h3 class=ex>Erklärung</h3>
<p>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.</p>
<h2 class="step">Erstelle eine Funktion um den Film zu bewegen</h2>
<h3 class=goal>Ziel</h3>
<p>Die <code>setInterval</code>-Funktion für eine einfache Funktion
verwenden.</p>
<h3 class=inst>Anweisungen</h3>
<p>Gestern haben wir gesehen, dass <code>setInterval</code> benutzt werden kann
um eine Funktion alle x Millisekunden auszuführen. Wir können das
Ausführen der Funktion auch stoppen, indem wir
<code>clearInterval</code> verwenden. Erweitere
<span class="filename">slideshow.js</span> um den folgenden Code und
lade dann die Seite neu:</p>
<pre>
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);
</pre>
<p> Warum eignen sich <code>for</code>- und <code>while</code>-Schleifen
nicht für diesen Effekt?</p>
<p>Versuch, die Geschwindigkeit der Bewegung zu erhöhen. Es gibt zwei
Wege. Welcher funktioniert besser?</p>
<p>Ändere die Funktion <code>move</code> so, dass sie den Film
alle 50 Millisekunden um 20 Pixel bewegt.</p>
<p>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.</p>
<p>Tipp: <code>Math.min</code> ist eine Funktion, die beliebig viele
Zahl-Werte als Parameter annimmt und den kleinsten Wert zurück gibt.
Probier mal das:</p>
<pre>
current = Math.min(current + 20, end);
</pre>
<p>Lass sich die Fotos nach links bewegen statt nach rechts.</p>
<p>Um wieviel musst du den Film bewegen um vom ersten Foto zum zweiten
zu gehen?</p>
<p>Was passiert wenn die Breite deines Fotos kein Vielfaches von 20 ist?
Wie kannst du das Problem umgehen?</p>
<p>Ändere die Funktion <code>move</code>, so dass die Bewegungsrichtung
nur von den Start- und Endwerten abhängt.</p>
<h3 class=ex>Erklärung</h3>
<p>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.</p>
<p>Wir haben nun immer <code>setInterval</code> statt einer
<code>while</code>- oder <code>for</code>-Schleife benutzt, um die Zeit
zwischen den Aufrufen beeinflussen zu können, statt Tausender kleinster
Veränderungen in Tausenden von Aufrufen zu machen.</p>
<p>Am Ende könnte deine Funktion beispielsweise so aussehen:</p>
<pre>
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);
}
}
</pre>
<p>Mit den Funktionen <code>Math.min</code> und <code>Max.max</code>
können wir sicher stellen, dass der Wert von <code>current</code> nie
den Wert von <code>end</code> überschreitet. Dabei können wir den Wert
von <code>current</code> entweder kleiner oder größer halten – je nach
Bewegungsrichtung.</p>
<h2 class="step">Eine Animations-Funktion bauen</h2>
<h3 class=goal>Ziel</h3>
<p>Schreibe eine wiederverwendbare Animations-Funktion die mehrfach
ausgeführt werden kann.</p>
<h3 class=inst>Anweisungen</h3>
<p>Schreibe eine Funktion namens <code>scroll</code> die eine
Startposition und eine Endposition als Parameter nimmt.</p>
<pre>
function scroll(start, end) {
// und nun?
}
</pre>
<p>Platziere die Zählvariable <code>current</code>, deine
<code>move</code>-Funktion und <code>setInterval</code> in deine neue
Funktion <code>scroll</code>. Variablen für Start und Ende musst du
nicht mehr definieren. Deine Datei
<span class="filename">slideshow.js</span> wird etwa so aussehen:</p>
<pre>
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);
}
</pre>
<p>Lade die Seite im Browser neu.</p>
<p>Benutze nun deine <code>scroll</code>-Funktion um zum zweiten Foto zu
wechseln. Tippe dazu in die Konsole:</p>
<pre>
scroll(0, -500);
</pre>
<p>(… wobei statt <code>500</code> die Breite deines Fotos angegeben
wird.)</p>
<p>Benutze die <code>scroll</code>-Funktion um vom zweiten zum dritten
Foto zu wechseln.</p>
<p>Wechsele zurück zum zweiten Foto.</p>
<h3 class=ex>Erklärung</h3>
<p>Nun haben wir eine einzige Funktion, mit der wir von links nach
rechts und von jeder Start- zu jeder Endposition wechseln können!</p>
<h2 class="step">Auf das <code>keydown</code>-Event reagieren</h2>
<h3 class=goal>Ziel</h3>
<p>Herausfinden, wie wir den Nutzer die Slideshow bedienen lassen können.</p>
<h3 class=inst>Anweisungen</h3>
<p>Füge in <span class="filename">slideshow.js</span> einen
<em>Event Listener</em> namens <code>handleEvent</code> für das
<code>document</code>-Objekt hinzu. Der Event Listener ist eine
Funktion, die im Falle eines <code>keydown</code>-Events ausgeführt
werden soll. Die Funktion „hört“ also sozusagen auf das Ereignis
„Taste runter“:</p>
<pre>
function handleEvent(e) {
console.log(e, e.keyCode);
}
document.addEventListener('keydown', handleEvent);
</pre>
<p>Stelle sicher, dass die Developer Tools in Chrome geöffnet sind.</p>
<p>Lade die Seite neu.</p>
<p>Drücke Tasten auf deiner Tastatur und beobachte, was dabei in der
Konsole ausgegeben wird.</p>
<p>Was sind die <code>keyCode</code>s für die linke und rechte
Pfeiltaste?</p>
<p>Erweitere die <code>handleEvent</code>-Funktion, so dass sie eine
Funktion aufruft, die den Film nach links bzw. rechts bewegt, wenn die
linke oder rechte Pfeiltaste gedrückt wird:</p>
<pre>
function handleEvent(e) {
backAndForth(e.keyCode);
}
function backAndForth(keyCode) {
if (keyCode == 37) {
scroll(500, 0);
}
if (keyCode == 39) {
scroll(0, 500);
}
}
</pre>
<p>(… wobei statt <code>500</code> die Breite deines Fotos angegeben
<p>Teste die neue Funktion im Browser. Denke daran, die Seite immer neu
zu laden, wenn du deinen JavaScript-Code im Editor geändert hast.</p>
<p>Warum bewegt es sich nicht weiter in die selbe Richtung, wenn du die
selbe Pfeiltaste drückst?</p>
<p>Speichere die aktuelle Position in einer Variable und aktualisiere
den Wert dieser Variable nach dem Aufrufen der
<code>scroll</code>-Funktion. Benutze die aktuelle Position immer als
den Wert für <code>start</code> when du die <code>scroll</code>-Funktion
aufrufst.</p>
<p>Probier es erstmal alleine! Wenn du aber Hilfe brauchst, darfst du
hier spicken:</p>
<pre>
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;
}
}
</pre>
<h3 class=ex>Erklärung</h3>
<p>Wenn JavaScript in deinem Browser ausgeführt wird (also immer, außer
es ist abgeschalten), „lauscht“ es durchgehend auf <em>Events</em>, 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
<code>keydown</code>-Events, die vom <code>document</code> ausgehen.</p>
<p>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.</p>
<p>Durch lauschen auf <em>Eingaben</em> des Besuchers können wir ihm
erlauben, die Seite zu steuern.</p>
<p>Damit kann man eine Menge machen!</p>
<h2 class="step">Bugs finden und korrigieren</h2>
<h3 class=goal>Ziel</h3>
<p>Lernen, Events zu ignorieren, wenn eine Reaktion unerwünscht wäre.</p>
<h3 class=inst>Anweisungen</h3>
<p>Unsere Funktionen um auf Events zu lauschen und zu animieren haben
einen Fehler, einen <em>Bug</em>. 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.</p>
<p>Weißt du, was den Fehler verursacht? Wie kannst du ihn verhinden?</p>
<p>Versuche diesen Bug zu fixen.</p>
<h3 class=ex>Erklärung</h3>
<p>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.)</p>
<p>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.</p>
<p>Hast du eine Lösung gefunden? Hier ist ein Vorschlag dafür:</p>
<pre>
<strong>var scrolling = false;</strong>
function scroll(start, end) {
var current = start;
var move = function () {
filmroll.style.left = current + 'px';
<strong>
if (current == end) {
clearInterval(loop);
scrolling = false;
}
</strong>
if (end > start) {
current = Math.min(current + 20, end);
} else {
current = Math.max(current - 20, end);
}
}
var loop = setInterval(move, 50);
<strong>scrolling = true;</strong>
}
function handleEvent(e) {
<strong>if (!scrolling) {
backAndForth(e.keyCode);
}</strong>
}
</pre>
<p>Wir haben eine Variable erzeugt in der wir uns merken ob sich der
Film gerade bewegt. Falls er das tut, können wir das
<code>keydown</code>-Event ignorieren wenn es eintritt.</p>
<p>Diese Lösung verwendet ein Ausrufungszeichen in der
<code>if (!scrolling)</code>-Bedingung (in der Funktion
<code>handleEvent</code>). Das Ausrufungszeichen nennt man den
logischen NOT-Operator in JavaScript (also „nicht“, eine Verneinung).
Die Bedingung <code>if (!scrolling)</code> bedeutet also: falls die Variable
<code>scrolling</code> nicht true (wahr) ist.</p>
<p>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?</p>
<h2>Weiter!</h2>
<p>Jetzt wo wir Änderungen am CSS gemacht haben, wollen wir auch das
HTML verändern!</p>
<p><a href="page4_de.html">→ Zur vierten Seite</a>.</p>