JavaScript-Grundlagen I
Dieses Skriptum begleitet Sie durch die ersten Schritte mit JavaScript — der dritten und letzten Kerntechnologie der Webentwicklung. Nach HTML (Struktur) und CSS (Darstellung) bringt JavaScript nun Verhalten und Interaktivität auf Ihre Webseiten.
1. Was ist JavaScript?
JavaScript (kurz JS) wurde 1995 von Brendan Eich in nur zehn Tagen bei Netscape entwickelt. Trotz des Namens hat JavaScript nichts mit der Sprache Java zu tun — der Name war eine Marketing-Entscheidung. Heute ist JavaScript die mit Abstand am weitesten verbreitete Programmiersprache im Web.
Die drei Säulen des Web
| Technologie | Aufgabe | Dateityp |
|---|---|---|
| HTML | Struktur und Inhalt | .html |
| CSS | Darstellung und Layout | .css |
| JavaScript | Verhalten und Interaktivität | .js |
Anders als HTML (eine Auszeichnungssprache) und CSS (eine Stylesheet-Sprache) ist
JavaScript eine echte Programmiersprache. Das bedeutet: Sie können
damit Entscheidungen treffen (if/else), Aktionen wiederholen (Schleifen),
Daten verarbeiten und auf Benutzereingaben reagieren.
JavaScript einbinden
Es gibt drei Wege, JavaScript in eine HTML-Seite einzubinden:
1. Externes Skript (empfohlen):
<script src="skript.js" defer></script>
2. Internes Script-Tag:
<script>
console.log('Hallo von JavaScript!');
</script>
3. Inline (nicht empfohlen):
<button onclick="alert('Klick!')">Klick mich</button>
Best Practice
Verwenden Sie immer ein externes Skript mit dem defer-Attribut. So wird
das Script erst ausgeführt, nachdem das gesamte HTML geladen ist. Das vermeidet
Probleme, wenn JavaScript auf HTML-Elemente zugreift, die noch nicht existieren.
Die Browser-Konsole
Die Konsole ist Ihr wichtigstes Werkzeug zum Testen und Debuggen. Öffnen Sie sie
mit F12 und wählen Sie den Tab „Console". Dort können Sie JavaScript-Befehle
direkt eintippen und sofort das Ergebnis sehen.
console.log('Hallo Welt!'); // Gibt Text aus
console.log(42); // Gibt eine Zahl aus
console.log('Name:', 'Schuchardt'); // Mehrere Werte
console.warn('Achtung!'); // Warnung (gelb)
console.error('Fehler!'); // Fehler (rot)
console.table({name: 'Hugo', jahr: 1842}); // Tabelle
Ausprobieren
Öffnen Sie die Browser-Konsole (F12 → Console) und tippen Sie ein:
2 + 3, dann 'Hugo' + ' ' + 'Schuchardt', dann
typeof 42. Beobachten Sie die Ergebnisse.
2. Variablen und Datentypen
Variablen sind benannte Speicherplätze. Sie geben einem Wert einen Namen, damit Sie ihn später wiederverwenden können. In JavaScript gibt es zwei Schlüsselwörter zum Erstellen von Variablen:
const und let
// const — Konstante: Wert kann nicht neu zugewiesen werden
const name = 'Hugo Schuchardt';
const geburtsjahr = 1842;
const istLinguist = true;
// let — Variable: Wert kann sich ändern
let briefZaehler = 0;
briefZaehler = briefZaehler + 1; // jetzt 1
briefZaehler = briefZaehler + 1; // jetzt 2
const vs. let
const ist die Standard-Wahl. Verwenden Sie const immer dann,
wenn der Wert sich nicht ändern soll (das ist der häufigste Fall).
let verwenden Sie nur, wenn der Wert sich im Laufe des
Programms ändern muss (z.B. bei Zählern oder Status-Variablen).
var ist veraltet und sollte nicht mehr verwendet werden.
Primitive Datentypen
JavaScript kennt mehrere grundlegende (primitive) Datentypen:
String — Text in Anführungszeichen:
const titel = 'Brief an Otto Benndorf';
const stadt = "Graz";
const satz = `${name} lebte in ${stadt}`; // Template Literal
Number — Ganze Zahlen und Dezimalzahlen:
const jahr = 1879;
const laenge = 3.5;
const negativ = -10;
Boolean — Wahrheitswert:
const istPubliziert = true;
const hatAntwort = false;
Spezialwerte:
const leer = null; // Bewusst „kein Wert"
let unbekannt; // undefined — noch kein Wert zugewiesen
console.log(unbekannt); // undefined
typeof — Typ herausfinden
console.log(typeof 'Hallo'); // "string"
console.log(typeof 42); // "number"
console.log(typeof true); // "boolean"
console.log(typeof null); // "object" (bekannter JS-Bug!)
console.log(typeof undefined); // "undefined"
Vorsicht
typeof null gibt "object" zurück — das ist ein historischer
Fehler in JavaScript, der aus Kompatibilitätsgründen nicht behoben wurde. Lassen Sie
sich davon nicht verwirren: null ist kein Objekt, sondern bedeutet
„bewusst leer".
Namenskonventionen
Variablennamen in JavaScript folgen der camelCase-Konvention: Das erste Wort beginnt klein, jedes weitere Wort beginnt mit einem Großbuchstaben.
const briefTitel = 'Brief an Benndorf'; // camelCase
const absenderName = 'Hugo Schuchardt'; // camelCase
const empfangsJahr = 1879; // camelCase
const MAX_BRIEFE = 100; // UPPER_SNAKE_CASE für Konstanten
Ausprobieren
Erstellen Sie in der Konsole Variablen für einen Brief: const absender,
const empfaenger, const jahr, const ort.
Geben Sie jedem einen passenden Wert und prüfen Sie den Typ mit typeof.
3. Arrays und Objekte
Arrays — geordnete Listen
Ein Array ist eine geordnete Sammlung von Werten. Jeder Wert hat einen Index (Position), der bei 0 beginnt.
const sprachen = ['Deutsch', 'Romanisch', 'Baskisch', 'Kreolisch'];
// Zugriff über Index (beginnt bei 0!)
console.log(sprachen[0]); // "Deutsch"
console.log(sprachen[2]); // "Baskisch"
// Anzahl der Elemente
console.log(sprachen.length); // 4
// Element hinzufügen
sprachen.push('Keltisch');
console.log(sprachen.length); // 5
// Letztes Element entfernen
const entfernt = sprachen.pop();
console.log(entfernt); // "Keltisch"
Wichtig
Der Index beginnt bei 0, nicht bei 1! Das erste Element hat Index 0,
das zweite Index 1, usw. Das letzte Element hat den Index
array.length - 1.
Objekte — Schlüssel-Wert-Paare
Ein Objekt speichert zusammengehörige Daten als Paare aus Schlüssel (Key) und Wert (Value). Das ist ideal für strukturierte Daten wie Metadaten zu einem Brief.
const brief = {
titel: 'Brief an Karl Vossler',
absender: 'Hugo Schuchardt',
empfaenger: 'Karl Vossler',
jahr: 1904,
ort: 'Graz',
sprache: 'Deutsch'
};
// Zugriff mit Punkt-Notation
console.log(brief.titel); // "Brief an Karl Vossler"
console.log(brief.jahr); // 1904
// Zugriff mit Klammer-Notation
console.log(brief['ort']); // "Graz"
// Alle Schlüssel auflisten
console.log(Object.keys(brief));
// ["titel", "absender", "empfaenger", "jahr", "ort", "sprache"]
// Alle Werte auflisten
console.log(Object.values(brief));
// ["Brief an Karl Vossler", "Hugo Schuchardt", "Karl Vossler", 1904, "Graz", "Deutsch"]
Arrays von Objekten
In der Praxis arbeitet man häufig mit Arrays, die Objekte enthalten — zum Beispiel eine Sammlung von Briefen:
const briefe = [
{ titel: 'Brief an Benndorf', jahr: 1879, ort: 'Graz' },
{ titel: 'Brief an Vossler', jahr: 1904, ort: 'Graz' },
{ titel: 'Brief an Meringer', jahr: 1910, ort: 'Graz' }
];
console.log(briefe[0].titel); // "Brief an Benndorf"
console.log(briefe.length); // 3
// Über alle Briefe iterieren
for (const brief of briefe) {
console.log(`${brief.titel} (${brief.jahr})`);
}
Ausprobieren
Erstellen Sie ein Array korrespondenten mit mindestens drei Namen von
Schuchardt-Korrespondenten. Geben Sie das gesamte Array aus, dann den zweiten Eintrag,
und fügen Sie einen neuen hinzu.
4. Operatoren und Ausdrücke
Arithmetische Operatoren
const a = 10;
const b = 3;
console.log(a + b); // 13 (Addition)
console.log(a - b); // 7 (Subtraktion)
console.log(a * b); // 30 (Multiplikation)
console.log(a / b); // 3.333... (Division)
console.log(a % b); // 1 (Rest/Modulo)
console.log(a ** b); // 1000 (Potenz: 10 hoch 3)
// Praktisch: Alter berechnen
const geburtsjahr = 1842;
const todesjahr = 1927;
const alter = todesjahr - geburtsjahr;
console.log(`Alter: ${alter} Jahre`); // "Alter: 85 Jahre"
Vergleichsoperatoren
// Strikter Vergleich (=== und !==) — IMMER verwenden!
console.log(5 === 5); // true
console.log(5 === '5'); // false (Zahl vs. String)
console.log(5 !== 3); // true
// Größer/Kleiner
console.log(1904 > 1879); // true
console.log(1904 < 1879); // false
console.log(1904 >= 1904); // true
console.log(1904 <= 1900); // false
== vs. ===
Verwenden Sie immer den strikten Vergleich ===. Der
lockere Vergleich == wandelt Typen automatisch um, was zu überraschenden
Ergebnissen führt: '5' == 5 ist true, aber
'5' === 5 ist false (korrekterweise).
Logische Operatoren
const jahr = 1904;
const sprache = 'Deutsch';
// UND (&&) — beide Bedingungen müssen wahr sein
console.log(jahr > 1900 && sprache === 'Deutsch'); // true
// ODER (||) — mindestens eine Bedingung muss wahr sein
console.log(jahr < 1800 || sprache === 'Deutsch'); // true
// NICHT (!) — kehrt den Wahrheitswert um
console.log(!(jahr === 1904)); // false
String-Verkettung und Template Literals
const vorname = 'Hugo';
const nachname = 'Schuchardt';
// String-Verkettung mit +
const name1 = vorname + ' ' + nachname;
// Template Literal mit Backticks (empfohlen!)
const name2 = `${vorname} ${nachname}`;
// Ausdrücke im Template Literal
const info = `${vorname} ${nachname} wurde ${1927 - 1842} Jahre alt.`;
console.log(info); // "Hugo Schuchardt wurde 85 Jahre alt."
// Mehrzeilige Strings
const html = `
<div class="person">
<h2>${vorname} ${nachname}</h2>
<p>Sprachwissenschaftler in Graz</p>
</div>
`;
Template Literals
Template Literals (Backtick-Strings) sind die bevorzugte Methode für Strings in
modernem JavaScript. Sie erlauben das Einbetten von Variablen und Ausdrücken mit
${...} und unterstützen mehrzeilige Strings. Besonders beim Erzeugen
von HTML-Fragmenten sind sie unverzichtbar.
5. Kontrollstrukturen
if / else — Bedingte Ausführung
Mit if/else können Sie Code nur dann ausführen, wenn eine bestimmte
Bedingung erfüllt ist:
const jahr = 1879;
if (jahr > 1900) {
console.log('20. Jahrhundert');
} else if (jahr > 1800) {
console.log('19. Jahrhundert');
} else {
console.log('Vor dem 19. Jahrhundert');
}
// Ausgabe: "19. Jahrhundert"
Praxisbeispiel — Briefe kategorisieren:
const brief = { seiten: 4, sprache: 'Deutsch', jahr: 1904 };
if (brief.sprache === 'Deutsch' && brief.jahr > 1900) {
console.log('Deutscher Brief aus dem 20. Jahrhundert');
} else if (brief.sprache === 'Deutsch') {
console.log('Deutscher Brief aus dem 19. Jahrhundert');
} else {
console.log('Fremdsprachiger Brief');
}
for-Schleife — Code wiederholen
// Klassische for-Schleife mit Zähler
for (let i = 0; i < 5; i++) {
console.log(`Durchlauf ${i}`);
}
// Durchlauf 0, Durchlauf 1, ... Durchlauf 4
for...of — Über Arrays iterieren
const korrespondenten = ['Benndorf', 'Vossler', 'Meringer', 'Nyrop'];
for (const name of korrespondenten) {
console.log(`Brief an ${name}`);
}
// Brief an Benndorf
// Brief an Vossler
// Brief an Meringer
// Brief an Nyrop
while-Schleife
let zaehler = 0;
while (zaehler < 3) {
console.log(`Zähler: ${zaehler}`);
zaehler++;
}
// Zähler: 0, Zähler: 1, Zähler: 2
Empfehlung
Für das Iterieren über Arrays ist for...of die modernste und lesbarste
Methode. Verwenden Sie die klassische for-Schleife nur, wenn Sie den
Index benötigen. while ist nützlich, wenn die Anzahl der Durchläufe
nicht vorab bekannt ist.
Ausprobieren
Erstellen Sie ein Array mit den Jahren [1879, 1885, 1904, 1910, 1920].
Iterieren Sie mit for...of darüber und geben Sie für jedes Jahr aus,
ob es im 19. oder 20. Jahrhundert liegt.
6. Funktionen
Funktionen fassen einen Block von Code zusammen, den man mit einem Namen aufrufen und wiederverwenden kann. Sie können Parameter entgegennehmen und einen Wert zurückgeben.
Funktionsdeklaration
function begruessung(name) {
return `Hallo ${name}, willkommen im Archiv!`;
}
const text = begruessung('Hugo Schuchardt');
console.log(text); // "Hallo Hugo Schuchardt, willkommen im Archiv!"
Mehrere Parameter
function briefInfo(absender, empfaenger, jahr) {
return `Brief von ${absender} an ${empfaenger} (${jahr})`;
}
console.log(briefInfo('Schuchardt', 'Vossler', 1904));
// "Brief von Schuchardt an Vossler (1904)"
Arrow Functions
Arrow Functions sind eine kompaktere Schreibweise, die vor allem in modernem JavaScript häufig verwendet wird:
// Klassische Funktion
function verdopple(zahl) {
return zahl * 2;
}
// Arrow Function — gleiche Funktion
const verdopple = (zahl) => {
return zahl * 2;
};
// Kurzform: Bei einem einzelnen Ausdruck
const verdopple = (zahl) => zahl * 2;
// Bei einem Parameter: Klammern optional
const verdopple = zahl => zahl * 2;
Arrow Functions mit Array-Methoden:
const jahre = [1879, 1885, 1904, 1910, 1920];
// filter — nur bestimmte Elemente behalten
const nachNeunzehnhundert = jahre.filter(j => j > 1900);
console.log(nachNeunzehnhundert); // [1904, 1910, 1920]
// map — jedes Element umwandeln
const jahrhundert = jahre.map(j => j > 1900 ? '20. Jh.' : '19. Jh.');
console.log(jahrhundert);
// ["19. Jh.", "19. Jh.", "20. Jh.", "20. Jh.", "20. Jh."]
// find — erstes passendes Element finden
const erstesZwanzigstes = jahre.find(j => j > 1900);
console.log(erstesZwanzigstes); // 1904
Wann welche Form?
Verwenden Sie Funktionsdeklarationen (function name() {})
für benannte, eigenständige Funktionen. Verwenden Sie Arrow Functions
(() => {}) als Callback-Parameter (z.B. bei addEventListener,
filter, map). Beide Formen sind korrekt — LLMs verwenden
häufig Arrow Functions, deshalb müssen Sie sie lesen können.
Ausprobieren
Schreiben Sie eine Funktion beschreibeBrief, die ein Brief-Objekt
({titel, jahr, ort}) entgegennimmt und einen formatierten String
zurückgibt, z.B. "Brief an Vossler (Graz, 1904)".
7. Das DOM verstehen
Wenn der Browser eine HTML-Datei lädt, erstellt er daraus eine interne Baumstruktur — das Document Object Model (DOM). Jedes HTML-Element wird zu einem „Knoten" (Node) in diesem Baum. JavaScript greift über das DOM auf die Seite zu und kann sie verändern.
// HTML-Dokument
<html>
<body>
<h1>Titel</h1>
<p id="info">Ein Absatz.</p>
</body>
</html>
// DOM-Baum (vereinfacht):
document
└── html
└── body
├── h1
│ └── #text "Titel"
└── p#info
└── #text "Ein Absatz."
Wichtige DOM-Begriffe
- document — Das gesamte Dokument als JavaScript-Objekt
- Element — Ein HTML-Tag im Baum (z.B.
<h1>,<p>) - Node (Knoten) — Oberbegriff: Elemente, Text-Knoten, Kommentare
- Parent (Eltern) — Das übergeordnete Element
- Children (Kinder) — Die untergeordneten Elemente
- Sibling (Geschwister) — Elemente auf der gleichen Ebene
Wenn JavaScript ein Element im DOM verändert (z.B. Text austauscht oder eine CSS-Klasse hinzufügt), aktualisiert der Browser sofort die Anzeige. Das ist das Grundprinzip jeder dynamischen Webseite.
8. DOM-Manipulation
Elemente auswählen
// querySelector — wie ein CSS-Selektor (empfohlen!)
const titel = document.querySelector('h1'); // Erstes h1
const info = document.querySelector('#info'); // Element mit id="info"
const brief = document.querySelector('.brief-text'); // Erstes mit class="brief-text"
const link = document.querySelector('nav a:first-child'); // Komplexer Selektor
// querySelectorAll — alle passenden Elemente
const absaetze = document.querySelectorAll('p');
console.log(absaetze.length); // Anzahl der p-Elemente
// Über die Ergebnisse iterieren
for (const p of absaetze) {
console.log(p.textContent);
}
Inhalte ändern
const titel = document.querySelector('h1');
// Nur Text setzen (sicher!)
titel.textContent = 'Hugo Schuchardt Archiv';
// HTML setzen (Vorsicht bei Nutzerdaten!)
titel.innerHTML = '<em>Hugo Schuchardt</em> Archiv';
CSS-Klassen steuern
const box = document.querySelector('.brief');
box.classList.add('hervorgehoben'); // Klasse hinzufügen
box.classList.remove('versteckt'); // Klasse entfernen
box.classList.toggle('aktiv'); // Klasse umschalten (an/aus)
box.classList.contains('aktiv'); // true oder false
Neue Elemente erstellen
// 1. Element erstellen
const neuerAbsatz = document.createElement('p');
// 2. Inhalt setzen
neuerAbsatz.textContent = 'Dieser Absatz wurde mit JavaScript erstellt.';
neuerAbsatz.classList.add('dynamisch');
// 3. In den DOM einfügen
document.querySelector('main').appendChild(neuerAbsatz);
Attribute lesen und setzen
const link = document.querySelector('a');
// Attribute lesen
console.log(link.href); // URL des Links
console.log(link.getAttribute('target')); // z.B. "_blank"
// Attribute setzen
link.setAttribute('title', 'Mehr erfahren');
link.href = 'https://schuchardt.uni-graz.at';
textContent vs. innerHTML
Verwenden Sie textContent, wenn Sie reinen Text setzen wollen — das ist
sicherer und schneller. Verwenden Sie innerHTML nur, wenn Sie bewusst
HTML-Elemente einfügen wollen. Setzen Sie niemals Benutzereingaben
direkt in innerHTML — das ermöglicht XSS-Angriffe (Cross-Site Scripting).
Ausprobieren
Öffnen Sie eine beliebige Webseite und die Konsole. Wählen Sie das erste
<h1>-Element mit document.querySelector('h1') und
ändern Sie seinen textContent und seine Farbe mit
style.color. Beobachten Sie, wie sich die Seite sofort ändert.
9. Event-Handling
Events sind Aktionen, die im Browser passieren: ein Klick, eine Tastatureingabe,
das Laden einer Seite. Mit addEventListener können Sie auf diese
Events reagieren.
addEventListener
const button = document.querySelector('#mein-button');
// Event-Listener hinzufügen
button.addEventListener('click', function() {
console.log('Button wurde geklickt!');
});
// Mit Arrow Function (kürzer)
button.addEventListener('click', () => {
console.log('Klick!');
});
Häufige Events
| Event | Auslöser | Typische Verwendung |
|---|---|---|
click | Mausklick | Buttons, Links, Bilder |
input | Wert in Eingabefeld ändert sich | Suchfelder, Formulare |
submit | Formular wird abgeschickt | Formulare |
mouseover | Maus über Element | Tooltips, Hover-Effekte |
keydown | Taste gedrückt | Tastaturkürzel |
Praxisbeispiel: Interaktive Seite
// HTML:
// <input type="text" id="suchfeld" placeholder="Brief suchen...">
// <p id="ergebnis"></p>
const suchfeld = document.querySelector('#suchfeld');
const ergebnis = document.querySelector('#ergebnis');
suchfeld.addEventListener('input', () => {
const suchbegriff = suchfeld.value;
if (suchbegriff.length > 2) {
ergebnis.textContent = `Suche nach: "${suchbegriff}"...`;
} else {
ergebnis.textContent = '';
}
});
Das Callback-Muster
Die Funktion in addEventListener wird nicht sofort ausgeführt — sie wird
als „Callback" gespeichert und erst aufgerufen, wenn das Event tatsächlich eintritt.
Das ist ein grundlegendes Muster in JavaScript: Code, der „später" ausgeführt wird.
10. XML im Browser parsen
JavaScript kann XML direkt im Browser verarbeiten — mit der eingebauten
DOMParser-API. Das ist besonders nützlich für die Arbeit mit
TEI-XML-Daten in den Digital Humanities.
DOMParser
const xmlString = `
<korrespondenz>
<brief id="001">
<absender>Hugo Schuchardt</absender>
<empfaenger>Otto Benndorf</empfaenger>
<datum>1879-05-12</datum>
<ort>Graz</ort>
</brief>
<brief id="002">
<absender>Hugo Schuchardt</absender>
<empfaenger>Karl Vossler</empfaenger>
<datum>1904-01-03</datum>
<ort>Graz</ort>
</brief>
</korrespondenz>
`;
// XML-String → DOM-Dokument
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, 'application/xml');
// Einzelne Werte extrahieren
const ersterBrief = xmlDoc.querySelector('brief');
console.log(ersterBrief.querySelector('absender').textContent);
// "Hugo Schuchardt"
// Alle Briefe finden
const alleBriefe = xmlDoc.querySelectorAll('brief');
for (const brief of alleBriefe) {
const emp = brief.querySelector('empfaenger').textContent;
const dat = brief.querySelector('datum').textContent;
console.log(`${emp} — ${dat}`);
}
getElementsByTagName
// Alternative Methode für XML
const briefe = xmlDoc.getElementsByTagName('brief');
console.log(briefe.length); // 2
for (let i = 0; i < briefe.length; i++) {
console.log(briefe[i].getAttribute('id'));
}
// "001", "002"
Hinweis zu Namespaces
TEI-XML verwendet einen Namespace (http://www.tei-c.org/ns/1.0). In
einigen Fällen muss man getElementsByTagNameNS verwenden oder den
Namespace im Selektor berücksichtigen. Für einfache Fälle funktioniert
querySelector allerdings auch ohne Namespace-Angabe.
11. TEI-XML zu HTML
Nun setzen wir alles zusammen: Wir laden ein TEI-XML-Dokument, parsen es, extrahieren die relevanten Daten und stellen sie als formatiertes HTML dar.
Schritt 1: TEI-XML bereitstellen
const teiXml = `
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<teiHeader>
<fileDesc>
<titleStmt>
<title>Brief von Hugo Schuchardt an Karl Vossler</title>
</titleStmt>
<publicationStmt>
<publisher>Hugo Schuchardt Archiv</publisher>
</publicationStmt>
<sourceDesc>
<p>Universitätsbibliothek Graz</p>
</sourceDesc>
</fileDesc>
</teiHeader>
<text>
<body>
<opener>
<dateline>Graz, 3. Jänner 1904</dateline>
<salute>Verehrter Herr Kollege!</salute>
</opener>
<p>Empfangen Sie meinen herzlichsten Dank für Ihre
freundliche Zusendung. Ich habe Ihre Arbeit mit
großem Interesse gelesen.</p>
<closer>
<salute>Mit vorzüglicher Hochachtung</salute>
<signed>Ihr Hugo Schuchardt</signed>
</closer>
</body>
</text>
</TEI>`;
Schritt 2: Parsen und Daten extrahieren
const parser = new DOMParser();
const doc = parser.parseFromString(teiXml, 'application/xml');
// Metadaten extrahieren
const titel = doc.querySelector('title').textContent;
const publisher = doc.querySelector('publisher').textContent;
// Brief-Inhalt extrahieren
const datum = doc.querySelector('dateline').textContent;
const anrede = doc.querySelector('opener salute').textContent;
const textAbsaetze = doc.querySelectorAll('body > p');
const gruss = doc.querySelector('closer salute').textContent;
const unterschrift = doc.querySelector('signed').textContent;
Schritt 3: Als HTML rendern
const ausgabe = document.querySelector('#brief-ausgabe');
// Text der Absätze sammeln
let briefText = '';
for (const p of textAbsaetze) {
briefText += `<p>${p.textContent}</p>`;
}
// HTML zusammenbauen
ausgabe.innerHTML = `
<article class="brief-anzeige">
<header>
<h2>${titel}</h2>
<p class="meta">Quelle: ${publisher}</p>
</header>
<div class="brief-kopf">
<p class="datum">${datum}</p>
<p class="anrede">${anrede}</p>
</div>
<div class="brief-text">
${briefText}
</div>
<div class="brief-schluss">
<p class="gruss">${gruss}</p>
<p class="unterschrift">${unterschrift}</p>
</div>
</article>
`;
Das Grundmuster: Daten laden → verarbeiten → darstellen
Dieses dreistufige Muster ist fundamental für Webanwendungen:
1. Laden: Daten aus einer Quelle holen (String, Datei, API)
2. Verarbeiten: Daten parsen und die relevanten Informationen extrahieren
3. Darstellen: Ergebnis als HTML in den DOM einfügen
Prompt-Beispiel
„Schreibe mir JavaScript-Code, der folgenden TEI-XML-String parst und als HTML darstellt. Der Brief soll mit Datum, Anrede, Text und Unterschrift angezeigt werden. Verwende DOMParser und Template Literals. Kommentiere jeden Schritt."
12. Agentic Coding: JavaScript-Code lesen
In dieser Einheit liegt der Agentic-Coding-Fokus auf zwei Kompetenzen: Code Literacy (CL) und Code Review (RV).
Code Literacy — Generierten Code lesen
Wenn ein LLM JavaScript-Code generiert, müssen Sie verstehen, was dieser Code tut. Hier ist eine systematische Strategie:
- Überblick: Lesen Sie Kommentare und Funktionsnamen. Was ist das Ziel des Codes?
- Variablen: Welche Daten werden gespeichert? Was bedeuten die Namen?
- Kontrollfluss: Gibt es
if/else, Schleifen, Funktionsaufrufe? - DOM-Zugriffe: Welche HTML-Elemente werden ausgewählt und verändert?
- Events: Auf welche Benutzeraktionen reagiert der Code?
Prompt für Code Literacy
„Erkläre mir diesen JavaScript-Code Schritt für Schritt. Was macht jede Zeile? Welche JavaScript-Konzepte werden verwendet? Erkläre es für Anfänger."
Code Review — Generierten Code prüfen
LLMs machen Fehler. Prüfen Sie generierten JavaScript-Code immer mit dieser Checkliste:
- Syntax: Sind alle Klammern geschlossen? Fehlen Semikolons?
- Selektoren: Existieren die referenzierten IDs und Klassen im HTML?
- Variablen: Werden
const/letkorrekt verwendet? Gibt es Tippfehler? - Typen: Wird
===statt==verwendet? - Timing: Wird der Code nach dem DOM-Laden ausgeführt (
defer)? - Sicherheit: Wird
innerHTMLmit Benutzerdaten verwendet? - Konsole: Gibt es Fehlermeldungen in den DevTools?
Häufige LLM-Fehler in JavaScript
- Selektoren, die nicht zum HTML passen (ID oder Klasse existiert nicht)
- Veraltete Syntax:
varstattlet/const - Fehlende Fehlerbehandlung (was passiert, wenn ein Element
nullist?) - Überkomplizierte Lösungen (mehr Code als nötig)
- Halluzinierte APIs (Methoden, die es nicht gibt)
Prompt für Code Review
„Überprüfe diesen JavaScript-Code auf Fehler und Verbesserungsmöglichkeiten. Achte besonders auf: Selektoren, Variablen-Deklaration, Typsicherheit, Fehlerbehandlung und Sicherheit. Erkläre jeden gefundenen Punkt."
Ausprobieren
Lassen Sie ein LLM folgenden Code generieren: „JavaScript, das alle Absätze auf einer Seite findet und deren Hintergrundfarbe bei Klick umschaltet." Lesen Sie den generierten Code Zeile für Zeile durch und prüfen Sie ihn mit der Review-Checkliste.