Signatur
Beschreibung
document.writeln() funktioniert genauso wie document.write(), hängt nach dem geschriebenen Inhalt aber einen Zeilenumbruch (\n) an. Der Text wird als HTML geparst und an der aktuellen Parser-Position in das Dokument eingefügt.
Läuft der Aufruf noch während das Dokument geladen wird (etwa in einem synchronen, nicht-defer/async-Skript), landet die Ausgabe direkt hinter dem aktuellen <script>-Element. Ist das Dokument schon fertig geladen, ruft writeln() selbst document.open() auf. Das löscht den kompletten bisherigen Inhalt der Seite. Den Stream schließt du danach mit document.close().
Der angehängte Zeilenumbruch ist in normalem HTML nur ein Leerraum und wird meistens zusammengefasst. Sichtbar wird er nur in Elementen wie <pre> oder <textarea> bzw. bei white-space: pre. Deshalb ist writeln() vor allem beim Erzeugen vorformatierter Ausgaben oder von Quelltext in neuen Fenstern und Iframes praktisch.
In modernem Code solltest du die Methode kaum noch verwenden. DOM-Methoden wie append(), insertAdjacentHTML() oder textContent sind sicherer, schneller und vorhersehbarer.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $...markup | string | TrustedHTML | Beliebig viele Strings oder TrustedHTML-Objekte. Sie werden ohne Trennzeichen aneinandergehängt, dann wird ein \n angefügt und das Ergebnis als HTML geparst. Andere Werte werden in Strings umgewandelt. |
Rückgabewert
undefined).Beispiele
Vorformatierte Ausgabe in einem neuen Fenster
const win = window.open('', 'report', 'width=500,height=400');
const doc = win.document;
doc.open();
doc.writeln('<!DOCTYPE html>');
doc.writeln('<title>Bericht</title>');
doc.writeln('<pre>');
const zeilen = ['Umsatz Q1: 12.400 €', 'Umsatz Q2: 15.100 €', 'Umsatz Q3: 13.900 €'];
zeilen.forEach((z) => doc.writeln(z)); // jede Angabe erscheint in einer eigenen Zeile
doc.writeln('</pre>');
doc.close(); // Stream schließen, damit das Laden abgeschlossen wird
Unterschied zwischen write() und writeln()
const iframe = document.createElement('iframe');
document.body.append(iframe);
const doc = iframe.contentDocument;
doc.open();
doc.write('<pre>');
doc.write('A');
doc.write('B'); // kein Umbruch → "AB"
doc.writeln(''); // Zeilenumbruch einfügen
doc.writeln('C');
doc.writeln('D');
doc.write('</pre>');
doc.close();
console.log(JSON.stringify(doc.querySelector('pre').textContent));
Mehrere Argumente und Trusted Types
// Mehrere Argumente werden ohne Trennzeichen verbunden
const iframe = document.createElement('iframe');
document.body.append(iframe);
const doc = iframe.contentDocument;
// Unter der CSP require-trusted-types-for 'script' ist TrustedHTML Pflicht
const policy = window.trustedTypes?.createPolicy('writer', {
createHTML: (s) => s.replace(/</g, '<')
});
const benutzerText = '<img src=x onerror=alert(1)>';
const sicher = policy ? policy.createHTML(benutzerText) : benutzerText.replace(/</g, '<');
doc.open();
doc.writeln('<p>', 'Eingabe: ', sicher, '</p>');
doc.close();
console.log(doc.body.textContent.trim());
// Wichtig · Fallstricke
Inhalt wird gelöscht: Rufst du writeln() auf, nachdem das Dokument fertig geladen ist (z. B. in einem Klick-Handler oder nach DOMContentLoaded), wird implizit document.open() ausgeführt und die ganze Seite ersetzt.
Sicherheit (XSS): Die übergebenen Strings werden als HTML geparst, eingebettete <script>-Elemente und Event-Handler-Attribute werden also ausgeführt. Schreibe Benutzereingaben nie ungefiltert. Maskiere sie oder erzeuge Text-Knoten über DOM-Methoden. Mit der CSP-Direktive require-trusted-types-for 'script' werden reine Strings abgelehnt (TypeError). Dann sind TrustedHTML-Objekte aus einer Trusted-Types-Policy Pflicht.
Performance und Einschränkungen: Chrome blockiert per document.write/writeln eingefügte, parserblockierende Drittanbieter-Skripte bei langsamen Verbindungen. Aus Skripten mit async oder defer und aus Skripten, die mit createElement eingefügt wurden, werden Aufrufe während des Ladens ignoriert (mit Konsolen-Warnung). In XHTML-Dokumenten (application/xhtml+xml) wirft die Methode einen InvalidStateError.
Kompatibilität: Die Methode wird von allen Browsern unterstützt. Die Spezifikation rät aber ausdrücklich davon ab. Den Zeilenumbruch siehst du nur in <pre>-Elementen o. Ä.