Skip to content

Commit 7753f0c

Browse files
committed
Zähler weiter
1 parent bb02546 commit 7753f0c

File tree

1 file changed

+222
-0
lines changed

1 file changed

+222
-0
lines changed
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
---
2+
title: Zähler
3+
order: 5
4+
---
5+
6+
Ein einfacher Zähler
7+
-------------------
8+
9+
An diesem Simplen Beispiel werden wir verschiedene
10+
Arten Javascript zu schreiben kennen lernen.
11+
12+
Hier ist die Ausgangsversion des Codes:
13+
14+
15+
<htmlcode>
16+
<input type="number" id="counter" value="0">
17+
<button onclick="increment()">Up</button>
18+
<button onclick="decrement()">Down</button>
19+
20+
<script>
21+
function increment() {
22+
const counter = document.getElementById('counter');
23+
counter.value = parseInt(counter.value) + 1;
24+
}
25+
26+
function decrement() {
27+
const counter = document.getElementById('counter');
28+
counter.value = parseInt(counter.value) - 1;
29+
}
30+
</script>
31+
</htmlcode>
32+
33+
34+
## addEventListener
35+
36+
Die Event-Listener sind als `onclick` Attribute in HTML gesetzt.
37+
Das kann man auch ganz von JavaScript aus machen, mit `addEventListener`.
38+
Dann hat man in HTML nur noch die Aufgabe die verschiednenen Elemente
39+
mit eindeutigen id's oder Klassen zu benennen. Alles weitere passiert in Javascript:
40+
41+
<htmlcode>
42+
<input type="number" id="counter" value="0">
43+
<button id="up">Up</button>
44+
<button id="down">Down</button>
45+
46+
<script>
47+
const counter = document.getElementById('counter');
48+
const upButton = document.getElementById('up');
49+
const downButton = document.getElementById('down');
50+
51+
function increment() {
52+
counter.value = parseInt(counter.value) + 1;
53+
}
54+
55+
function decrement() {
56+
counter.value = parseInt(counter.value) - 1;
57+
}
58+
59+
upButton.addEventListener('click', increment);
60+
downButton.addEventListener('click', decrement);
61+
</script>
62+
</htmlcode>
63+
64+
## Problemt mit der DOM
65+
66+
Achtung: wenn man das Javascript **vor** dem HTML in die
67+
Seite gibt, hat man ein Problem:
68+
69+
<htmlcode>
70+
<head>
71+
<title>Simple Counter</title>
72+
<script>
73+
const counter = document.getElementById('counter');
74+
const upButton = document.getElementById('up');
75+
const downButton = document.getElementById('down');
76+
77+
function increment() {
78+
counter.value = parseInt(counter.value) + 1;
79+
}
80+
81+
function decrement() {
82+
counter.value = parseInt(counter.value) - 1;
83+
}
84+
85+
upButton.addEventListener('click', increment);
86+
downButton.addEventListener('click', decrement);
87+
</script>
88+
</head>
89+
<body>
90+
<input type="number" id="counter" value="0">
91+
<button id="up">Up</button>
92+
<button id="down">Down</button>
93+
</body>
94+
</htmlcode>
95+
96+
Der Counter funktioniert nicht mehr, und in der Console sieht man die Fehlermeldung:
97+
98+
**Uncaught TypeError: can't access property "addEventListener", upButton is null**
99+
100+
Das Problem ist, dass der upButton noch gar nicht existiert, wenn der Code
101+
ausgeführt wird. `document.getElementById('up')` liefert dann den wert `null`,
102+
mit dem wir aber nicht weiter arbeiten können.
103+
104+
## Lösung DOMContentLoaded
105+
106+
Das Event `DOMContentLoaded` wird gefeuert, wenn die DOM vollständig
107+
ist:
108+
109+
<htmlcode>
110+
document.addEventListener('DOMContentLoaded', setupCounter);
111+
</htmlcode>
112+
113+
Die Funktion `setupCounter` müssen wir nur zuerst definieren,
114+
so sieht also das gesamte Beispiel aus:
115+
116+
<htmlcode>
117+
function setupCounter() {
118+
const counter = document.getElementById('counter');
119+
const upButton = document.getElementById('up');
120+
const downButton = document.getElementById('down');
121+
122+
function increment() {
123+
counter.value = parseInt(counter.value) + 1;
124+
}
125+
126+
function decrement() {
127+
counter.value = parseInt(counter.value) - 1;
128+
}
129+
130+
upButton.addEventListener('click', increment);
131+
downButton.addEventListener('click', decrement);
132+
}
133+
134+
document.addEventListener('DOMContentLoaded', setupCounter);
135+
</htmlcode>
136+
137+
## Javascript Klasse
138+
139+
Bisher ist der Wert des Zählers direkt im DOM-Element gespeichert.
140+
Bei komplexeren Beispielen wollen wir das sicher nicht mehr, da wollen
141+
wir Javascript Klassen verwenden.
142+
143+
Wir können also ein Klasse für den Zähler programmieren:
144+
145+
<javascript>
146+
class Counter {
147+
constructor(initialValue = 0) {
148+
this.value = initialValue;
149+
}
150+
151+
increment() {
152+
this.value++;
153+
this.updateDisplay();
154+
}
155+
156+
decrement() {
157+
this.value--;
158+
this.updateDisplay();
159+
}
160+
161+
updateDisplay() {
162+
document.getElementById('counter').value = this.value;
163+
}
164+
}
165+
</javascript>
166+
167+
### Erzeugen des Objekts und Anbindung an die DOM
168+
169+
In der setup-Funktion wird nun ein Objekt dieser Klasse
170+
erzeugt:
171+
172+
<javascript>
173+
function setupCounter() {
174+
const counter = new Counter(0);
175+
const upButton = document.getElementById('up');
176+
const downButton = document.getElementById('down');
177+
178+
upButton.addEventListener('click', counter.increment());
179+
downButton.addEventListener('click', counter.decrement());
180+
}
181+
182+
document.addEventListener('DOMContentLoaded', setupCounter);
183+
</javascript caption="mit Fehler">
184+
185+
Aber Achtung: dieser Code funktioniert nicht!
186+
187+
### EventListener richtig aufsetzen
188+
189+
Das Problem sind diese beiden Zeilen:
190+
191+
<javascript>
192+
upButton.addEventListener('click', counter.increment()); // FALSCH!
193+
downButton.addEventListener('click', counter.decrement()); // FALSCH!
194+
</javascript>
195+
196+
Wenn `addEventListener` ausgeführt wird, wird die Methode `counter.increment`
197+
einmal aufgerufen. Sie liefert keinen Rückgabewert, also `undefined`.
198+
Damit passiert dann bei jedem klick auf den Button ... nichts!
199+
200+
Zweiter Versuch:
201+
202+
<javascript>
203+
upButton.addEventListener('click', counter.increment); // FALSCH!
204+
downButton.addEventListener('click', counter.decrement); // FALSCH!
205+
</javascript>
206+
207+
Auch hier gibt es einen Error: **Uncaught TypeError: this.updateDisplay is not a function**.
208+
Hier funktioniert zwar der Aufruf der Methode, aber die Methode erhält
209+
als `this` eine referenz auf den geklickten Button. Diese setzen von `this`
210+
bei `addEventListener` gab es schon, bevor es Klassen gab. Heute ist
211+
es sehr unpraktisch.
212+
213+
214+
Um das Problem zu umgehen kann man eine Arrow Funkction verwenden,
215+
dann klappts auch mit dem `this`:
216+
217+
<javascript>
218+
upButton.addEventListener('click', () => counter.increment());
219+
downButton.addEventListener('click', () => counter.decrement());
220+
</javascript>
221+
222+

0 commit comments

Comments
 (0)