Die Seite verändern (DOM)
IT 12.6 – Webanwendungen · Einheit 3 · Café-App Schritt 3
Lernziele
Abschnitt betitelt „Lernziele“- Du kannst das DOM als Baum der Elemente einer Seite beschreiben.
- Du kannst Elemente mit
getElementById,querySelectorundquerySelectorAllfinden. - Du kannst Texte, Attribute und Klassen von Elementen mit JavaScript ändern.
- Du kannst neue Elemente erzeugen und HTML aus Daten zusammensetzen.
- Du kannst den Unterschied zwischen
textContentundinnerHTMLerläutern und begründet wählen.
Rückblick
Abschnitt betitelt „Rückblick“1. Was liefert preisFormatieren(1.5) aus der Café-App?
Den Text '1,50 €'.
2. Wann nimmst du let, wann const?
let, wenn der Wert sich später ändert (Zähler, Summe), sonst const.
3. Wie wählt man in CSS ein Element mit id=“preis” aus, wie alle mit class=“vegan”?
Mit #preis bzw. .vegan.
„Heute geöffnet?“
Abschnitt betitelt „„Heute geöffnet?““Auf der Startseite des Cafés steht, wann geöffnet ist. Viele lesen die Liste trotzdem falsch, gerade freitags. Besser wäre ein auffälliger Hinweis, der sich selbst anpasst: „Heute (Freitag) haben wir in der 1. großen Pause geöffnet.“ An Wochenenden soll er anders aussehen.
Die Funktion istGeoeffnet aus Schritt 2 weiß schon, ob geöffnet ist. Aber wie kommt das Ergebnis aus JavaScript auf die Seite?
Erkunden: JavaScript greift auf die Seite zu
Abschnitt betitelt „Erkunden: JavaScript greift auf die Seite zu“Bevor du weiterliest: Bearbeite die Erkundung. Die Erklärungen weiter unten helfen dir erst danach.
Erkundung: Fünf Zeilen, fünf Wirkungen mittel
Im JavaScript-Feld stehen fünf Zeilen, die alle mit // auskommentiert sind. Entferne die beiden Schrägstriche einer Zeile nach der anderen. Notiere vorher jeweils deine Vermutung.
Übungsbereich im Browser: Dein Code läuft abgeschottet in der Vorschau. Es wird nichts gespeichert. Sichere deine Arbeit mit „Herunterladen“.
Tab rückt ein. Mit Esc und dann Tab verlässt du das Feld.
a) Beschreibe die Wirkung jeder Zeile.
b) Vergleiche Zeile 2 und 3. Erkläre den Unterschied.
c) Vergleiche Zeile 4 und 5. Erkläre den Unterschied.
d) Ändere in Zeile 1 'titel' in 'Titel'. Beschreibe, was jetzt in der Konsole steht, und vermute warum.
Lösung
Das DOM
Abschnitt betitelt „Das DOM“Vergleicht eure Ergebnisse. Wenn der Browser eine HTML-Datei liest, baut er daraus einen Baum von Objekten im Speicher: das Document Object Model (DOM). Jedes Element ist ein Knoten, Elemente in einem anderen Element sind seine Kinder.
document└── html ├── head │ └── title └── body ├── h2 (id="titel") ├── ul │ ├── li │ └── li └── p (id="hinweis")JavaScript ändert nicht die HTML-Datei, sondern diesen Baum. Der Browser zeigt jede Änderung sofort an. Lädt man die Seite neu, ist alles wieder wie in der Datei. In den Entwicklerwerkzeugen (Reiter „Elemente“) siehst du den aktuellen Baum mit allen Änderungen. Mit Strg + U siehst du dagegen die ursprüngliche Datei.
Elemente finden
Abschnitt betitelt „Elemente finden“| Aufruf | liefert | Beispiel |
|---|---|---|
document.getElementById('hinweis') |
das Element mit dieser ID oder null |
ID ohne # |
document.querySelector('#hinweis') |
das erste Element zum CSS-Selektor oder null |
'.vegan', 'nav a', '#hinweis' |
document.querySelectorAll('li') |
alle passenden Elemente als Liste | mit forEach oder for … of durchlaufen |
Beide Schreibweisen sind verbreitet und kommen auch in Prüfungsaufgaben vor. Man speichert gefundene Elemente meist in einer Konstanten:
const hinweis = document.getElementById('hinweis');hinweis.textContent = 'Heute geöffnet';Inhalte, Attribute und Klassen ändern
Abschnitt betitelt „Inhalte, Attribute und Klassen ändern“| Eigenschaft oder Methode | Wirkung |
|---|---|
element.textContent = '…' |
Text setzen oder lesen (reiner Text) |
element.innerHTML = '…' |
Inhalt als HTML setzen oder lesen |
element.innerText |
ähnlich wie textContent, berücksichtigt aber die Darstellung (z. B. versteckte Teile) |
bild.src = 'neu.svg', bild.alt = '…', link.href = '…' |
Attribute ändern |
element.hidden = true |
Element ausblenden |
element.classList.add('offen') |
Klasse hinzufügen (remove, toggle, contains) |
element.style.color = 'red' |
einzelne CSS-Eigenschaft setzen |
Neue Elemente erzeugen
Abschnitt betitelt „Neue Elemente erzeugen“Weg 1: Element für Element
const liste = document.getElementById('angebot');const eintrag = document.createElement('li'); // neues li, noch nicht auf der Seiteeintrag.textContent = 'Brezel';eintrag.classList.add('vegan');liste.append(eintrag); // jetzt auf der Seite, am Ende der ListeMit element.remove() entfernt man ein Element wieder.
Weg 2: HTML-Text zusammensetzen und auf einmal einsetzen. So steht es oft in Prüfungsaufgaben:
const tage = ['Montag', 'Dienstag', 'Mittwoch'];let html = '';for (let i = 0; i < tage.length; i++) { html += '<li>' + tage[i] + '</li>';}document.getElementById('tage').innerHTML = html;Ergebnis im DOM:
<ul id="tage"> <li>Montag</li> <li>Dienstag</li> <li>Mittwoch</li></ul>Wann läuft das Skript?
Abschnitt betitelt „Wann läuft das Skript?“Ein Skript findet nur Elemente, die der Browser schon gelesen hat. Steht <script src="app.js"></script> im head ohne defer, läuft es, bevor der body existiert, und alle Suchen liefern null. Abhilfe:
<script src="app.js" defer></script>imhead(so in der Café-App), oder- das
script-Element ans Ende desbodysetzen (so oft in Prüfungsaufgaben).
Ältere Seiten nutzen auch <body onload="start()">: Die Funktion start läuft dann, wenn die Seite fertig geladen ist.
Café-App: Schritt 3
Abschnitt betitelt „Café-App: Schritt 3“Café-App, Schritt 3: „Heute geöffnet?“ mittel
- Ergänze in
index.htmldirekt unter der Überschrift „Öffnungszeiten“ einen leeren Absatz<p id="status"></p>. - Schreibe in
app.jseine FunktionzeigeStatus(). Sie bestimmt den heutigen Wochentag (new Date().getDay()) und schreibt in den Absatz zum Beispiel „Heute (Freitag) haben wir geöffnet.“ oder „Heute (Sonntag) haben wir geschlossen.“ - Je nach Ergebnis bekommt der Absatz die Klasse
offenodergeschlossen. Gestalte beide Klassen instyle.css, gut lesbar und nicht nur über die Farbe unterscheidbar. - Rufe die Funktion am Ende von
app.jsauf. - Öffne auch
speisekarte.html. Dort gibt es keinen Absatz mit der IDstatus. Sorge dafür, dass trotzdem kein Fehler in der Konsole erscheint.
Tipp 1
Für den Namen des Tages brauchst du eine Liste: const TAGE = ['Sonntag', 'Montag', …]; Dann ist TAGE[heute] der Name.
Tipp 2
Zu 5.: Was liefert getElementById, wenn es das Element nicht gibt? Prüfe das mit if, bevor du etwas setzt.
Stand nach Schritt 3
Aufgaben
Abschnitt betitelt „Aufgaben“Aufgabe 1: Code lesen – welches HTML entsteht? leicht
<div id="box"><p>alt</p></div>const box = document.getElementById('box');box.innerHTML = '<h3>Angebot</h3>';box.innerHTML += '<p class="hinweis">Heute ' + (2 + 1) + ' Sorten Muffins</p>';const p = document.createElement('p');p.textContent = '<b>nur solange der Vorrat reicht</b>';box.append(p);box.classList.add('aktiv');Gib den HTML-Code des div-Elements an, der nach dem Ausführen entsteht.
Lösung
Aufgabe 2: Raum frei oder belegt? mittel
Neben der Tür von Raum 104 hängt ein Tablet. Implementiere die Funktion zeigeRaum(belegt, bis):
- Ist
belegtgleichtrue, steht im Absatz#statusder TextBelegt bis 10:30(mit der Uhrzeit ausbis), und der Absatz hat die Klassebelegt. - Sonst steht dort
Frei, und der Absatz hat die Klassefrei. - Es darf immer nur eine der beiden Klassen gesetzt sein, auch wenn die Funktion mehrmals aufgerufen wird.
Übungsbereich im Browser: Dein Code läuft abgeschottet in der Vorschau. Es wird nichts gespeichert. Sichere deine Arbeit mit „Herunterladen“.
Tab rückt ein. Mit Esc und dann Tab verlässt du das Feld.
Selbstkontrolle – keine Bewertung.
Lösung
Aufgabe 3: Termine der Theater-AG mittel
Implementiere die Funktion zeigeTermine(termine). Sie bekommt eine Liste von Texten und schreibt für jeden Termin einen Listenpunkt in die Liste #termine. Ist die Liste leer, erscheint ein einziger Listenpunkt Keine Termine. Alte Einträge sollen dabei verschwinden.
Übungsbereich im Browser: Dein Code läuft abgeschottet in der Vorschau. Es wird nichts gespeichert. Sichere deine Arbeit mit „Herunterladen“.
Tab rückt ein. Mit Esc und dann Tab verlässt du das Feld.
Selbstkontrolle – keine Bewertung.
Tipp 1
Setze zuerst innerHTML der Liste auf ''. Durchlaufe dann die Termine mit einer for-Schleife.
Lösung
Aufgabe 4: Dreimal null mittel
In allen drei Fällen meldet die Konsole TypeError: Cannot set properties of null. Erläutere jeweils die Ursache und gib eine Verbesserung an.
a)
<p id="preis">…</p><script> document.getElementById('#preis').textContent = '1,50 €';</script>b)
<head> <script src="app.js"></script></head><body> <p id="preis">…</p></body>app.js: document.querySelector('#preis').textContent = '1,50 €';
c)
<p class="preis">…</p><script> document.querySelector('#preis').textContent = '1,50 €';</script>Lösung
Aufgabe 5: Das Gästebuch schwer
Auf der Seite eines Vereins kann man einen Gruß eingeben, der sofort unter dem Formular erscheint. Der Code:
const eingabe = document.getElementById('gruss');const liste = document.getElementById('gruesse');
function grussZeigen() { liste.innerHTML += '<li>' + eingabe.value + '</li>';}Jemand gibt statt eines Grußes ein: <img src="x" onerror="alert('Hallo')">
a) Beschreibe, was passiert.
b) Beurteile die Gefahr, wenn die Grüße später auf einem Server gespeichert und allen Besucherinnen und Besuchern angezeigt würden.
c) Gib eine verbesserte Fassung von grussZeigen an.
Tipp 1
Was macht innerHTML mit spitzen Klammern? Und was passiert bei einem Bild, das sich nicht laden lässt, wenn onerror gesetzt ist?
Lösung
Zusatzaufgabe: Vorlagen mit template schwer Zusatz
Ergänzend. HTML kennt das Element <template>: Sein Inhalt wird nicht angezeigt, sondern dient als Vorlage, die JavaScript kopieren und füllen kann.
Ergänze den Code so, dass für jedes Mitglied eine Kopie der Vorlage mit Name und Aufgabe in #vorstand erscheint.
Übungsbereich im Browser: Dein Code läuft abgeschottet in der Vorschau. Es wird nichts gespeichert. Sichere deine Arbeit mit „Herunterladen“.
Tab rückt ein. Mit Esc und dann Tab verlässt du das Feld.
Selbstkontrolle – keine Bewertung.
Lösung
Zusammenfassung
Abschnitt betitelt „Zusammenfassung“- Das DOM ist der Baum aller Elemente einer Seite im Speicher des Browsers. JavaScript verändert diesen Baum, nicht die Datei.
- Finden:
getElementById('id')(ohne#),querySelector('css')(das erste),querySelectorAll('css')(alle). Nichts gefunden:null. - Ändern:
textContent(Text),innerHTML(HTML), Attribute wiesrcundhref, Klassen mitclassList. - Erzeugen:
createElement,append,removeoder HTML-Text zusammensetzen und mitinnerHTMLeinsetzen. - Eingaben von Nutzerinnen und Nutzern mit
textContenteinsetzen, nie mitinnerHTML. - Das Skript braucht
deferoder steht am Ende desbody, sonst findet es die Elemente nicht.
Selbstcheck
Abschnitt betitelt „Selbstcheck“Geh die Fragen ehrlich durch. Wenn du bei einer unsicher bist, lies den verlinkten Abschnitt noch einmal oder bearbeite die passende Aufgabe.
- Kannst du das DOM beschreiben? → Das DOM
- Kannst du Elemente finden? → Erkundung, Elemente finden, Aufgabe 4
- Kannst du Texte, Attribute und Klassen ändern? → Inhalte, Attribute und Klassen ändern, Aufgabe 2, Café-App
- Kannst du neue Elemente erzeugen und HTML aus Daten zusammensetzen? → Neue Elemente erzeugen, Aufgabe 1, Aufgabe 3
- Kannst du
textContentundinnerHTMLunterscheiden und begründet wählen? → Erkundung, Aufgabe 5
Wortspeicher
Abschnitt betitelt „Wortspeicher“| Begriff | Bedeutung in einfachen Worten |
|---|---|
| DOM (Document Object Model) | Baum aller Elemente der Seite im Speicher des Browsers |
| Knoten | ein Element (oder ein Text) im DOM-Baum |
getElementById |
findet das Element mit einer bestimmten ID |
querySelector / querySelectorAll |
findet das erste bzw. alle Elemente zu einem CSS-Selektor |
null |
„nichts gefunden“ bzw. „kein Wert“ |
textContent |
Text eines Elements, ohne HTML |
innerHTML |
Inhalt eines Elements als HTML |
classList |
Klassen eines Elements hinzufügen, entfernen, umschalten |
createElement / append |
neues Element erzeugen / in die Seite einfügen |
| Cross-Site-Scripting (XSS) | Angriff, bei dem fremder Code über Eingaben in eine Seite gelangt |
defer |
Skript erst ausführen, wenn das ganze HTML gelesen ist |
Quellen
Abschnitt betitelt „Quellen“- Hessisches Kultusministerium: Kerncurriculum Fachoberschule, Fachrichtung Technik, Schwerpunkt Informationstechnik, Themenfeld 12.6 Webanwendungen, „dynamisches Aktualisieren der Darstellung“ (Stand November 2022).
- DOM nach dem WHATWG DOM Standard. Ausführliche, freie Dokumentation: MDN Web Docs, developer.mozilla.org/de (Du verlässt jetzt Maternet).
- Texte, Beispiele, Aufgaben und Code-Beispiele sind selbst erstellt.