bogen-treu nach docs/223015c/03-interaktivitaet-javascript-bogen.md: - 2 leads: kapitel-intro, 'statisch ist langweilig' - was-kann-JS-tabelle (mit sicherheits-grenzen erklärung), JS-timeline (1995 brendan eich → 2009 node → 2015 ES6 → heute TS) - JS einbinden (external/inline/module), js-console demo reuse - variablen (let/const/var, const default), datentypen (6 grundtypen + arrays/objects) - js-arrays + js-objects demo reuse, funktionen (declaration + arrow) - js-loops demo reuse, kontrollstrukturen (if/else, ternär, switch) - DOM lead, dom-tree demo reuse, querySelector (CSS-selektoren wiederverwendbar) - js-manipulate demo reuse (textContent/innerHTML/setAttribute/classList) - js-create demo reuse (createElement/appendChild/remove) - events lead, js-event-listener demo reuse, häufige-events-tabelle (click/input/submit/keydown/load/DOMContentLoaded) - js-preventdefault demo reuse, js-darkmode demo reuse, js-todo demo reuse, js-fetch demo reuse, js-localstorage demo reuse - frameworks lead, React/Vue/Angular/Svelte/Astro übersichtstabelle (KEINE logo-galerie), library-vs-framework (inversion of control) - selbstlernen mini-projekt (dark-mode / to-do / API), zusammenfassung des ganzen kurses reuse-demos: js-console, js-arrays, js-objects, js-loops, dom-tree, js-manipulate, js-create, js-event-listener, js-preventdefault, js-darkmode, js-todo, js-fetch, js-localstorage (13 demos reused) no NEU demos in dieser session per klausur-themen-vorschlag: JS NICHT klausurrelevant. lernziele auf verstehen-niveau (kein code-schreiben in klausur). streichungen vs altem 03-interaktivitaet-javascript.md (1050 zeilen, 49 slides): - framework-logo-galerie-folien (react/vue/svelte/astro/webpack/vite/parcel als jeweils eigene folie) → eine übersichts-folie - doppelte 'was kann JS'-folien → eine - lange hands-on-codes als folie → in speaker-notes oder selbstlernen verlinken klausurfolien.md regeneriert: 20 slides (8 aus kap1, 11 aus kap2, 0 aus kap3 → bestätigt JS-nicht-klausurrelevant-design) build geht durch
902 lines
22 KiB
Markdown
902 lines
22 KiB
Markdown
---
|
||
marp: true
|
||
theme: gaia
|
||
paginate: true
|
||
backgroundColor: #fff
|
||
header: "Grundlagen IT- und Internettechnik (223015c)"
|
||
footer: "Michael Czechowski – HdM Stuttgart – SoSe 2026"
|
||
title: "Kapitel 3: Interaktivität & JavaScript"
|
||
---
|
||
|
||
<style>
|
||
:root {
|
||
--color-foreground: #1a1a2e;
|
||
--color-highlight: #d63384;
|
||
--color-dimmed: #4a4a6a;
|
||
}
|
||
section.invert { --color-foreground: #fff; }
|
||
section { font-size: 1.7rem; }
|
||
h1 { color: #a02060; }
|
||
section.invert h1 { color: #fff; }
|
||
h2 { color: #1f2937; }
|
||
pre {
|
||
background: #0f0f23;
|
||
color: #d63384;
|
||
border-radius: 8px;
|
||
border-left: 3px solid #d63384;
|
||
}
|
||
pre code { background: transparent; color: inherit; }
|
||
code {
|
||
background: #0f0f23;
|
||
padding: 0.15em 0.4em;
|
||
border-radius: 4px;
|
||
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
||
}
|
||
section code:not(.hljs) { color: #d63384 !important; }
|
||
section code.hljs { color: #f8f8f8 !important; }
|
||
a { color: var(--color-highlight); }
|
||
section.aufgabe { background: #fce4ec !important; }
|
||
section.aufgabe footer { display: none; }
|
||
section.erklaerung { font-size: 1.1rem; }
|
||
section.erklaerung h1 { font-size: 1.5rem; color: #a02060; margin-bottom: 0.3rem; }
|
||
</style>
|
||
|
||
<!-- _class: lead -->
|
||
|
||
# Kapitel 3
|
||
## Interaktivität & JavaScript
|
||
|
||
<!--
|
||
Eine Stunde, eine Frage: *Was passiert, wenn HTML + CSS da sind und nichts reagiert?*
|
||
|
||
JavaScript (JS) macht Webseiten interaktiv:
|
||
- DOM manipulieren (Elemente ändern, hinzufügen, entfernen)
|
||
- Auf Events reagieren (Klick, Tastendruck, Scroll)
|
||
- Daten holen (fetch) + speichern (localStorage)
|
||
- Animationen, dynamische UI, SPA-Frameworks
|
||
|
||
Per Klausur-Themen-Vorschlag: JavaScript ist nicht klausurrelevant. Lernziele auf Verstehen-Niveau (Code-Lesen, nicht Code-Schreiben).
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _class: lead -->
|
||
|
||
# „Statisch ist langweilig"
|
||
|
||
<!--
|
||
Hook: eine reine HTML+CSS-Seite reagiert auf nichts. Klick auf Button → nichts passiert (außer Form-Submit).
|
||
|
||
JS bringt das Reagieren rein. Daher der Name „Interaktivität".
|
||
|
||
Beispiele aus dem Alltag:
|
||
- Dropdown-Menü, das aufklappt
|
||
- Dark-Mode-Toggle
|
||
- „Mehr laden"-Button ohne Page-Reload
|
||
- Live-Validierung in Formularen
|
||
- Maps, die zoomen
|
||
- Spotify-Player, der weitermacht beim Wechseln der Seite
|
||
-->
|
||
|
||
---
|
||
|
||
# Was kann JavaScript?
|
||
|
||
| Kann | Beispiel |
|
||
|------|----------|
|
||
| DOM ändern | Element-Text, -Klasse, -Inhalt manipulieren |
|
||
| Events behandeln | Klick, Tastendruck, Scroll, Submit |
|
||
| Daten holen | `fetch()` API-Anfragen |
|
||
| Daten lokal speichern | `localStorage`, `sessionStorage` |
|
||
| Animationen | `requestAnimationFrame`, CSS-Animationen triggern |
|
||
| Web-APIs nutzen | Geolocation, Camera, Audio, Notification |
|
||
|
||
**Aus Sicherheitsgründen NICHT:** willkürlich Dateien auf der Platte lesen/schreiben.
|
||
|
||
<!--
|
||
JavaScript läuft im Browser-Sandkasten. Es darf:
|
||
- alles am DOM ändern
|
||
- Daten an Server schicken (mit CORS-Beschränkungen)
|
||
- LocalStorage für ~5-10 MB nutzen
|
||
- Mit User-Erlaubnis: GPS, Kamera, Mikrofon, Push-Notifications
|
||
|
||
JS darf NICHT (ohne User-Aktion):
|
||
- Beliebige Dateien lesen oder schreiben (FileSystem-Access nur mit User-Picker)
|
||
- Auf andere Tabs / Fenster zugreifen (Same-Origin-Policy)
|
||
- Direkt zu beliebigen Servern verbinden (CORS-Schutz)
|
||
|
||
Außerhalb des Browsers: Node.js erlaubt JS, alles zu tun was eine Programmiersprache normal kann (Files, Netzwerk, Kindprozesse). Davon später (in DHBW-Modul).
|
||
-->
|
||
|
||
---
|
||
|
||
# JavaScript-Timeline
|
||
|
||
| Jahr | Was |
|
||
|------|-----|
|
||
| **1995** | Brendan Eich entwickelt JS in 10 Tagen für Netscape |
|
||
| 1997 | ECMAScript-1 standardisiert (offizieller Name) |
|
||
| 2009 | **Node.js** — JS auch außerhalb des Browsers |
|
||
| **2015** | ES6 (große Erneuerung: `let`, `const`, arrow functions, classes, modules) |
|
||
| 2017+ | jährliche Updates (ES2017, ES2018, …) |
|
||
| heute | TypeScript als statisch-getypter Aufsatz |
|
||
|
||
JS ist die **am weitesten verbreitete** Programmiersprache der Welt.
|
||
|
||
<!--
|
||
Brendan Eich bekam 10 Tage um JavaScript zu entwickeln — daher viele frühe Quirks (`null` ist ein object, `0 == "0"` ist true). Diese Quirks bleiben aus Kompatibilitätsgründen.
|
||
|
||
Node.js (2009) hat alles verändert: JS ist nicht mehr nur Browser-Spielzeug, sondern serverseitig nutzbar. Heute laufen viele große Websites auf Node-Backend (Netflix, LinkedIn, Walmart).
|
||
|
||
ES6 (2015) brachte JS auf moderne Sprachen-Niveau:
|
||
- `let` und `const` statt `var`
|
||
- Arrow functions: `(x) => x * 2`
|
||
- Classes (Syntax-Sugar für Prototyp-Vererbung)
|
||
- Modules: import/export
|
||
|
||
Seitdem: jährliche Updates mit kleineren Features.
|
||
-->
|
||
|
||
---
|
||
|
||
# JavaScript einbinden
|
||
|
||
```html
|
||
<!-- External (best practice) -->
|
||
<script src="./app.js"></script>
|
||
|
||
<!-- Inline (für kleine Snippets) -->
|
||
<script>
|
||
console.log('Hallo Welt');
|
||
</script>
|
||
|
||
<!-- Modern: als Modul -->
|
||
<script type="module" src="./main.js"></script>
|
||
```
|
||
|
||
**Modern:** als ES-Modul mit `type="module"`. Erlaubt `import` / `export`.
|
||
|
||
<!--
|
||
Drei Wege, JS in HTML einzubinden:
|
||
1. External via `<script src="...">` — Best Practice für nicht-triviale Apps
|
||
2. Inline mit `<script>...</script>` — für ganz kleine Snippets, ok
|
||
3. ES-Modul mit `type="module"` — für moderne Apps mit import/export
|
||
|
||
Wichtig: Script-Position
|
||
- `<script>` im `<head>` ohne Defer/Async: blockiert das Rendern
|
||
- `<script defer>` im head: parallel laden, vor DOMContentLoaded ausführen
|
||
- `<script async>`: parallel laden, sofort ausführen (gefährlich für Reihenfolge)
|
||
- `<script>` am Ende des `<body>`: erst nach HTML-Parsing
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _header: '' -->
|
||
<!-- _footer: '' -->
|
||
|
||

|
||
|
||
<!--
|
||
Die Browser-Konsole ist die wichtigste JS-Spielwiese für Anfänger.
|
||
|
||
DevTools öffnen (F12), Tab „Console":
|
||
- `console.log('Hallo')` → Hallo
|
||
- `1 + 1` → 2
|
||
- `let x = 10` → undefined, dann `x` → 10
|
||
- `document.title` → aktueller Tab-Titel
|
||
- `document.body.style.background = 'pink'` → Hintergrund wird pink
|
||
|
||
Studis können in der Konsole alles erst mal ausprobieren, bevor sie eine richtige .js-Datei schreiben.
|
||
-->
|
||
|
||
---
|
||
|
||
# Variablen — Daten speichern
|
||
|
||
```javascript
|
||
let name = "Ada"; // veränderlich
|
||
const PI = 3.14159; // konstant
|
||
var alt = "vermeiden"; // pre-ES6, hat skopen-bugs
|
||
|
||
// Verändern:
|
||
name = "Grace"; // OK
|
||
PI = 3.0; // FEHLER: const kann nicht überschrieben werden
|
||
```
|
||
|
||
**Faustregel:** `const` als Default. Nur `let`, wenn man umzuweisen plant. Niemals `var`.
|
||
|
||
<!--
|
||
Variable-Deklaration:
|
||
- `let`: Block-skopisch, veränderlich
|
||
- `const`: Block-skopisch, nicht-überschreibbar
|
||
- `var`: function-skopisch, hat historische Bugs — vermeiden
|
||
|
||
`const` heißt nicht „unveränderlich" — bei Objekten/Arrays kann der Inhalt verändert werden, nur die Referenz nicht.
|
||
|
||
```javascript
|
||
const list = [1, 2, 3];
|
||
list.push(4); // OK — Array selbst ist mutiert
|
||
list = []; // FEHLER — Referenz kann nicht überschrieben werden
|
||
```
|
||
-->
|
||
|
||
---
|
||
|
||
# Datentypen
|
||
|
||
```javascript
|
||
let text = "Hallo"; // string
|
||
let zahl = 42; // number
|
||
let ist_an = true; // boolean
|
||
let nichts = null; // null
|
||
let nicht_gesetzt; // undefined
|
||
let liste = [1, 2, 3]; // array
|
||
let objekt = { x: 1 }; // object
|
||
|
||
typeof text // "string"
|
||
typeof liste // "object" (auch arrays sind objects)
|
||
```
|
||
|
||
**6 Grund-Typen** + objects/arrays.
|
||
|
||
<!--
|
||
JavaScript ist dynamisch typisiert: eine Variable kann verschiedene Typen halten.
|
||
|
||
`typeof` zeigt den Typ. Arrays und Objects sind beide „object" — historische Quirks.
|
||
|
||
Modern: TypeScript fügt statische Typen drüber:
|
||
```typescript
|
||
let zahl: number = 42;
|
||
let text: string = "Hallo";
|
||
```
|
||
|
||
Das ist ein Aufsatz, der zu JavaScript kompiliert wird.
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _header: '' -->
|
||
<!-- _footer: '' -->
|
||
|
||

|
||
|
||
<!--
|
||
Arrays = geordnete Listen.
|
||
|
||
```javascript
|
||
let früchte = ["Apfel", "Banane", "Kirsche"];
|
||
|
||
früchte[0] // "Apfel"
|
||
früchte.length // 3
|
||
früchte.push("Datte") // hängt an
|
||
früchte.includes("Banane") // true
|
||
früchte.indexOf("Kirsche") // 2
|
||
|
||
// Array-Methoden:
|
||
früchte.map(f => f.toUpperCase()) // ["APFEL", ...]
|
||
früchte.filter(f => f.length > 5) // ["Banane", "Kirsche"]
|
||
früchte.forEach(f => console.log(f))
|
||
```
|
||
|
||
Alles 0-indiziert.
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _header: '' -->
|
||
<!-- _footer: '' -->
|
||
|
||

|
||
|
||
<!--
|
||
Objekte = Sammlung von Key-Value-Paaren.
|
||
|
||
```javascript
|
||
let person = {
|
||
name: "Ada",
|
||
alt: 56,
|
||
hobbies: ["Mathe", "Schach"]
|
||
};
|
||
|
||
person.name // "Ada"
|
||
person["name"] // "Ada" (gleich wie oben)
|
||
person.alt = 57 // ändern
|
||
|
||
// Schlüssel:
|
||
Object.keys(person) // ["name", "alt", "hobbies"]
|
||
```
|
||
|
||
JSON ist Objekt-Notation.
|
||
-->
|
||
|
||
---
|
||
|
||
# Funktionen
|
||
|
||
```javascript
|
||
// Function declaration
|
||
function gruessen(name) {
|
||
return "Hallo " + name;
|
||
}
|
||
|
||
// Arrow function (modern, kompakt)
|
||
const gruessen = (name) => "Hallo " + name;
|
||
|
||
// Mit mehreren Zeilen
|
||
const summe = (a, b) => {
|
||
const result = a + b;
|
||
return result;
|
||
};
|
||
|
||
gruessen("Ada") // "Hallo Ada"
|
||
summe(3, 4) // 7
|
||
```
|
||
|
||
<!--
|
||
Funktionen sind in JS „first-class" — können als Variable, als Argument, als Rückgabe-Wert verwendet werden.
|
||
|
||
Arrow Functions sind die moderne Form (ES6+):
|
||
- Kürzer
|
||
- Kein eigener `this`-Kontext
|
||
- Implizites Return bei One-Liner
|
||
|
||
Best Practice: arrow functions als default, function declaration wenn man hoisting braucht.
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _header: '' -->
|
||
<!-- _footer: '' -->
|
||
|
||

|
||
|
||
<!--
|
||
Schleifen — Wiederholungen.
|
||
|
||
```javascript
|
||
// for-Schleife (klassisch)
|
||
for (let i = 0; i < 5; i++) {
|
||
console.log(i); // 0, 1, 2, 3, 4
|
||
}
|
||
|
||
// for...of (über Array)
|
||
for (const frucht of ["A", "B", "C"]) {
|
||
console.log(frucht);
|
||
}
|
||
|
||
// forEach (Array-Methode)
|
||
[1, 2, 3].forEach(n => console.log(n));
|
||
|
||
// map (transformieren)
|
||
[1, 2, 3].map(n => n * 2); // [2, 4, 6]
|
||
|
||
// filter (auswählen)
|
||
[1, 2, 3, 4].filter(n => n > 2); // [3, 4]
|
||
```
|
||
|
||
Modern: bevorzuge map/filter/forEach über klassische for-Loops.
|
||
-->
|
||
|
||
---
|
||
|
||
# Kontrollstrukturen
|
||
|
||
```javascript
|
||
// if / else
|
||
if (age >= 18) {
|
||
console.log("erwachsen");
|
||
} else if (age >= 14) {
|
||
console.log("jugendlich");
|
||
} else {
|
||
console.log("kind");
|
||
}
|
||
|
||
// Ternärer Operator (Kurzform)
|
||
const status = age >= 18 ? "erwachsen" : "kind";
|
||
|
||
// switch (mehrere Werte)
|
||
switch (browser) {
|
||
case "Chrome": return "Blink";
|
||
case "Safari": return "WebKit";
|
||
case "Firefox": return "Gecko";
|
||
default: return "unknown";
|
||
}
|
||
```
|
||
|
||
<!--
|
||
Bedingungen mit if/else if/else — wie in vielen Sprachen.
|
||
|
||
Ternärer Operator ist ein Kurzschluss für einfache if/else: `condition ? a : b`.
|
||
|
||
switch für viele Werte, oft mit return statt break. Aber: modern oft durch Map oder Object-Lookup ersetzt:
|
||
```javascript
|
||
const engine = { Chrome: "Blink", Safari: "WebKit" }[browser];
|
||
```
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _class: lead -->
|
||
|
||
# Das DOM
|
||
## HTML im Speicher des Browsers
|
||
|
||
<!--
|
||
Pivot. Bis hier war JS allgemeine Programmierung. Jetzt: JS im Web-Kontext.
|
||
|
||
DOM = Document Object Model. Browser bauen aus HTML einen JavaScript-zugreifbaren Baum. JS kann diesen Baum manipulieren.
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _header: '' -->
|
||
<!-- _footer: '' -->
|
||
|
||

|
||
|
||
<!--
|
||
DOM als Baum-Struktur.
|
||
|
||
Jedes HTML-Element wird zu einem JS-Object. Diese Objects sind verbunden:
|
||
- parent: das Eltern-Element
|
||
- children: die Kind-Elemente
|
||
- nextSibling, previousSibling: die Nachbarn
|
||
|
||
Wenn JS den DOM ändert, ändert sich SOFORT die Anzeige.
|
||
|
||
Wichtig: JS kann nicht das HTML auf der Festplatte ändern — nur das DOM IM BROWSER. Wenn die Seite neu geladen wird, ist alles weg.
|
||
-->
|
||
|
||
---
|
||
|
||
# Elemente finden
|
||
|
||
```javascript
|
||
// EIN Element (erstes match)
|
||
const heading = document.querySelector('h1');
|
||
const btn = document.querySelector('#submit-button');
|
||
const card = document.querySelector('.card');
|
||
|
||
// MEHRERE Elemente (NodeList)
|
||
const allButtons = document.querySelectorAll('button');
|
||
const allCards = document.querySelectorAll('.card');
|
||
|
||
// Iterieren
|
||
allButtons.forEach(btn => console.log(btn.textContent));
|
||
```
|
||
|
||
`querySelector(...)` nimmt **denselben Selektor wie CSS.**
|
||
|
||
<!--
|
||
querySelector + querySelectorAll sind die modernen Wege, Elemente im DOM zu finden.
|
||
|
||
CSS-Selektoren wiederverwendbar:
|
||
- `'h1'` — alle h1
|
||
- `'#header'` — Element mit id
|
||
- `'.card'` — Elemente mit class
|
||
- `'nav > a'` — direkte Kinder
|
||
- `'input[type="email"]'` — Attribut-Selektor
|
||
|
||
Alternative ältere Methoden (querySelector ersetzt sie alle):
|
||
- `getElementById('header')`
|
||
- `getElementsByClassName('card')`
|
||
- `getElementsByTagName('h1')`
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _header: '' -->
|
||
<!-- _footer: '' -->
|
||
|
||

|
||
|
||
<!--
|
||
Elemente manipulieren — drei Hauptzugriffe:
|
||
|
||
```javascript
|
||
const el = document.querySelector('.greeting');
|
||
|
||
// Text-Inhalt
|
||
el.textContent = 'Hallo Welt';
|
||
|
||
// HTML-Inhalt (gefährlich — XSS-Risiko bei User-Input!)
|
||
el.innerHTML = '<strong>Achtung!</strong>';
|
||
|
||
// Attribute
|
||
el.setAttribute('href', 'https://librete.ch');
|
||
el.getAttribute('class');
|
||
|
||
// Klassen
|
||
el.classList.add('active');
|
||
el.classList.remove('hidden');
|
||
el.classList.toggle('open');
|
||
```
|
||
|
||
innerHTML ist mächtig, aber bei User-Input gefährlich — XSS-Angriffe möglich. Lieber textContent + createElement.
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _header: '' -->
|
||
<!-- _footer: '' -->
|
||
|
||

|
||
|
||
<!--
|
||
Elemente neu erzeugen:
|
||
|
||
```javascript
|
||
const newP = document.createElement('p');
|
||
newP.textContent = 'Frisch gemacht';
|
||
newP.classList.add('notice');
|
||
|
||
document.body.appendChild(newP);
|
||
|
||
// Elemente entfernen
|
||
const old = document.querySelector('.old-stuff');
|
||
old.remove();
|
||
```
|
||
|
||
Verwendung: To-Do-Items dynamisch hinzufügen, Chat-Nachrichten anzeigen, Modal öffnen.
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _class: lead -->
|
||
|
||
# Events
|
||
## Auf User-Aktionen reagieren
|
||
|
||
<!--
|
||
Events = Ereignisse, die im Browser passieren:
|
||
- click, dblclick
|
||
- input, change (Form-Elemente)
|
||
- submit (Form)
|
||
- keydown, keyup
|
||
- scroll, resize
|
||
- load, DOMContentLoaded
|
||
|
||
JS kann auf Events „lauschen" und reagieren.
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _header: '' -->
|
||
<!-- _footer: '' -->
|
||
|
||

|
||
|
||
<!--
|
||
Event-Listener: callback function wird ausgeführt, wenn Event passiert.
|
||
|
||
```javascript
|
||
const btn = document.querySelector('#myBtn');
|
||
|
||
btn.addEventListener('click', () => {
|
||
console.log('Klick!');
|
||
btn.textContent = 'Geklickt';
|
||
});
|
||
|
||
// Mit Event-Objekt
|
||
btn.addEventListener('click', (event) => {
|
||
console.log(event.target); // welches Element
|
||
console.log(event.clientX); // Maus-X-Koordinate
|
||
});
|
||
|
||
// Mehrere Listener auf einem Element möglich
|
||
btn.addEventListener('click', handler1);
|
||
btn.addEventListener('click', handler2);
|
||
```
|
||
|
||
Modern: addEventListener statt onclick-Attribut.
|
||
-->
|
||
|
||
---
|
||
|
||
# Häufige Events
|
||
|
||
| Event | Wo | Wann |
|
||
|-------|----|----|
|
||
| `click` | jedes Element | Maus-Klick |
|
||
| `input` | input, textarea, select | bei jedem Tastendruck |
|
||
| `change` | input, select | wenn Wert verändert (bei blur) |
|
||
| `submit` | form | wenn Form abgeschickt wird |
|
||
| `keydown` | document, input | beim Tastendruck |
|
||
| `scroll` | window, scrollbare Elemente | beim Scrollen |
|
||
| `load` | window | wenn Seite + Resources geladen |
|
||
| `DOMContentLoaded` | document | wenn DOM bereit (vor Bildern) |
|
||
|
||
<!--
|
||
Pro Event-Typ andere Anwendung:
|
||
- input vs change: input feuert bei jedem Tastendruck, change erst wenn der Cursor das Feld verlässt
|
||
- submit auf form: erlaubt preventDefault um Standard-Verhalten zu unterbinden
|
||
- load: alles geladen (Bilder, CSS) — oft zu spät für JS
|
||
- DOMContentLoaded: DOM ready — best practice, JS hier starten
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _header: '' -->
|
||
<!-- _footer: '' -->
|
||
|
||

|
||
|
||
<!--
|
||
preventDefault: verhindert die Standard-Reaktion.
|
||
|
||
```javascript
|
||
// Form ohne page-reload submitten
|
||
form.addEventListener('submit', (e) => {
|
||
e.preventDefault(); // verhindert Standard-Reload
|
||
// stattdessen: fetch + JSON
|
||
});
|
||
|
||
// Link, der nicht navigieren soll
|
||
link.addEventListener('click', (e) => {
|
||
e.preventDefault();
|
||
// stattdessen: Modal öffnen
|
||
});
|
||
```
|
||
|
||
Wichtig für moderne Single-Page-Apps — Navigation wird komplett von JS gesteuert.
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _header: '' -->
|
||
<!-- _footer: '' -->
|
||
|
||

|
||
|
||
<!--
|
||
Dark-Mode-Toggle — Klassiker.
|
||
|
||
```javascript
|
||
const toggle = document.querySelector('#darkmode-toggle');
|
||
const body = document.body;
|
||
|
||
toggle.addEventListener('click', () => {
|
||
body.classList.toggle('dark-mode');
|
||
});
|
||
```
|
||
|
||
CSS:
|
||
```css
|
||
body.dark-mode {
|
||
background: #1a1a2e;
|
||
color: #fff;
|
||
}
|
||
```
|
||
|
||
In ~10 Zeilen Code + ein bisschen CSS. Erste „echte" interaktive App für Anfänger.
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _header: '' -->
|
||
<!-- _footer: '' -->
|
||
|
||

|
||
|
||
<!--
|
||
To-Do-Liste — der „Hello World" der Web-Apps.
|
||
|
||
```javascript
|
||
const form = document.querySelector('#todo-form');
|
||
const input = document.querySelector('#todo-input');
|
||
const list = document.querySelector('#todo-list');
|
||
|
||
form.addEventListener('submit', (e) => {
|
||
e.preventDefault();
|
||
const text = input.value.trim();
|
||
if (!text) return;
|
||
|
||
const li = document.createElement('li');
|
||
li.textContent = text;
|
||
list.appendChild(li);
|
||
|
||
input.value = '';
|
||
});
|
||
```
|
||
|
||
Konzepte zusammen:
|
||
- Form-Submit + preventDefault
|
||
- Element erzeugen (createElement)
|
||
- Element anhängen (appendChild)
|
||
- Form zurücksetzen
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _header: '' -->
|
||
<!-- _footer: '' -->
|
||
|
||

|
||
|
||
<!--
|
||
fetch — Daten holen.
|
||
|
||
```javascript
|
||
fetch('https://api.github.com/users/torvalds')
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
console.log(data.name); // "Linus Torvalds"
|
||
console.log(data.public_repos);
|
||
})
|
||
.catch(error => console.error(error));
|
||
|
||
// Mit async/await (moderne syntax)
|
||
async function ladeUser() {
|
||
const res = await fetch('https://api.github.com/users/torvalds');
|
||
const data = await res.json();
|
||
return data;
|
||
}
|
||
```
|
||
|
||
Modern: async/await statt then-Chains.
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _header: '' -->
|
||
<!-- _footer: '' -->
|
||
|
||

|
||
|
||
<!--
|
||
localStorage — Daten persistent speichern (im Browser).
|
||
|
||
```javascript
|
||
// Speichern (nur Strings möglich)
|
||
localStorage.setItem('username', 'Ada');
|
||
|
||
// Laden
|
||
const name = localStorage.getItem('username');
|
||
|
||
// Object speichern: erst JSON
|
||
const settings = { darkmode: true, lang: 'de' };
|
||
localStorage.setItem('settings', JSON.stringify(settings));
|
||
|
||
// Laden: JSON parsen
|
||
const saved = JSON.parse(localStorage.getItem('settings'));
|
||
|
||
// Löschen
|
||
localStorage.removeItem('username');
|
||
localStorage.clear(); // alles weg
|
||
```
|
||
|
||
5-10 MB pro Origin. Bleibt zwischen Sessions. Nicht für sensible Daten (nicht verschlüsselt).
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _class: lead -->
|
||
|
||
# Frameworks
|
||
## Wann braucht man die?
|
||
|
||
<!--
|
||
Frameworks sind „voll-tooled" Abstraktionen über die DOM-API.
|
||
|
||
Wenn der Code mehr als ~500 Zeilen hat, wird vanilla DOM-Manipulation unübersichtlich. Frameworks helfen mit:
|
||
- Komponentenmodell
|
||
- Reactive State (Daten ändert sich, UI passt automatisch an)
|
||
- Routing
|
||
- Tools (Build, Linter, Tests)
|
||
-->
|
||
|
||
---
|
||
|
||
# React · Vue · Angular · Svelte
|
||
|
||
| Framework | Typ | Stärke |
|
||
|-----------|-----|--------|
|
||
| **React** | Library (mit Ökosystem) | dominierend, große Community |
|
||
| **Vue** | Framework | sanfter Einstieg, gute Doku |
|
||
| **Angular** | Framework | „Enterprise"-Setup, Google |
|
||
| **Svelte** | Compiler | kein Virtual DOM, kleine Bundle |
|
||
| **Astro** | Hybrid | Static-First, Multi-Framework |
|
||
|
||
Alle: **Komponenten** als Konzept. **State** verändert sich → UI re-rendert.
|
||
|
||
<!--
|
||
Übersicht ohne Galerie-Inflation.
|
||
|
||
Aktuelle Markt-Verteilung (2025-2026):
|
||
- React: ~40% (mit Next.js Framework drum herum)
|
||
- Vue: ~15-20% (Vue 3 + Nuxt)
|
||
- Angular: ~10% (in Enterprise)
|
||
- Svelte: ~5% (wächst stark)
|
||
- Astro: ~3% (für Content-sites)
|
||
- Vanilla: ~25% (klein-Projekte, Landing Pages)
|
||
|
||
Konzeptionell sind alle ähnlich: Komponenten, State, Re-Render.
|
||
|
||
Studis sollen wissen DASS es Frameworks gibt, aber für 223015c nicht im Detail. Tiefere Behandlung in Webentwicklung-Modulen (z.B. DHBW-Curriculum).
|
||
-->
|
||
|
||
---
|
||
|
||
# Library vs. Framework
|
||
|
||
| | Library | Framework |
|
||
|--|---------|-----------|
|
||
| Wer ruft | **du** rufst die Library | das Framework ruft **dich** |
|
||
| Beispiel | jQuery, React (offiziell), Lodash | Angular, Vue, Next.js, Astro |
|
||
| Vorteil | mehr Freiheit | mehr Struktur |
|
||
| Nachteil | mehr Setup-Arbeit | weniger Flexibilität |
|
||
|
||
**„Inversion of Control":** Library = du kontrollierst, Framework = es kontrolliert dich.
|
||
|
||
<!--
|
||
Begriffsklärung:
|
||
- Library: Sammlung von Funktionen. Du entscheidest wann/wie sie aufgerufen werden. Beispiel: `_.map(...)` von Lodash.
|
||
- Framework: Skelett, das deinen Code aufruft. Du füllst nur die richtigen Stellen. Beispiel: Angular Component Lifecycle Hooks.
|
||
|
||
Grenzen sind unscharf. React positioniert sich als Library, wird mit Next.js als Framework ergänzt. Vue mit/ohne Nuxt.
|
||
|
||
Faustregel: wenn du `npm run dev` für etwas Eigenes brauchst, ist es ein Framework.
|
||
-->
|
||
|
||
---
|
||
|
||
<!-- _class: aufgabe -->
|
||
|
||
# Selbstlernen — eigenes Mini-Projekt
|
||
|
||
Wähle eines:
|
||
|
||
**A. Dark-Mode-Toggle** — Button auf einer Seite, der `dark`-Klasse am body togglet. localStorage merkt den Zustand.
|
||
|
||
**B. To-Do-App** — Form, das neue Items zur Liste hinzufügt. localStorage für Persistenz.
|
||
|
||
**C. API-Visualisierung** — fetch zu `jsonplaceholder.typicode.com/users` und Daten als Liste rendern.
|
||
|
||
**Bonus:** mit GitHub Pages deployen → öffentlich zugängliche URL.
|
||
|
||
<!--
|
||
Niederschwellige Praxis-Aufgabe. ~30-60 Minuten pro Variante.
|
||
|
||
Tools:
|
||
- VS Code als Editor
|
||
- Live-Server-Extension oder einfach Doppelklick auf HTML-Datei
|
||
- Browser-DevTools für Debug
|
||
|
||
Lernziele:
|
||
- Eigenes Mini-Projekt produzieren
|
||
- DOM-Manipulation in Praxis
|
||
- Events handhaben
|
||
- API-Anfrage stellen (Variante C)
|
||
- Code öffentlich teilen (Bonus mit GitHub Pages)
|
||
-->
|
||
|
||
---
|
||
|
||
# Zusammenfassung
|
||
|
||
**Was JS macht:** DOM manipulieren · Events behandeln · Daten holen + speichern.
|
||
|
||
**Was JS NICHT macht (ohne User-Aktion):** willkürliche Datei-/Hardware-Zugriffe.
|
||
|
||
**Patterns:** querySelector → manipulate → addEventListener.
|
||
|
||
**Frameworks (React, Vue, …):** Abstraktion + State + Komponenten — für Projekte ab ~500 Zeilen.
|
||
|
||
→ **Du hast jetzt:** verstanden wie Daten reisen (Kap 2), wie sie dargestellt werden (HTML+CSS, Kap 1+2), und wie sie *interaktiv* werden (JS, Kap 3). Das ganze moderne Web in drei Kapiteln.
|
||
|
||
<!--
|
||
Recap Kap 3 + Synthese des ganzen Kurses.
|
||
|
||
Ende des Kurses:
|
||
- Pioniere → Architektur → Internet → HTML → CSS → A11y → JS
|
||
- Studis haben einen vollständigen mentalen Bauplan des Webs
|
||
|
||
Anschluss:
|
||
- Webentwicklung-Module: tieferer Stack (React, Node, Datenbanken, Deployment)
|
||
- DHBW-Module: Industrie-Praxis-Stack
|
||
|
||
Klausur:
|
||
- Hauptsächlich Kap 1+2 (Geschichte, Netzwerk, HTML, CSS, A11y)
|
||
- JS nur konzeptionell (Block J auf Verstehen-Niveau)
|
||
-->
|