Signatur
Beschreibung
replaceWith() kommt aus dem Mixin ChildNode und steht deshalb auch auf DocumentType zur Verfügung. Die Methode entfernt den Doctype-Knoten aus seinem Elternknoten (in der Regel dem Document) und fügt an derselben Stelle die übergebenen Knoten ein. Zeichenketten werden dabei automatisch in Text-Knoten umgewandelt.
In der Praxis braucht man das vor allem dann, wenn man Dokumente programmgesteuert erzeugt oder umbaut, etwa XML-Dokumente aus DOMParser oder mit document.implementation.createDocument() erstellte Dokumente. Dort kann man eine veraltete DTD-Referenz durch einen neuen Doctype ersetzen oder den Doctype durch einen Kommentar austauschen, bevor man das Dokument mit XMLSerializer ausgibt.
Wichtig ist, dass die Knotenhierarchie des Dokuments eingehalten wird: Ein Document darf höchstens einen Doctype haben, der vor dem Wurzelelement stehen muss. Außerdem darf ein Dokument keine Text-Knoten als Kinder haben. Deshalb sind als Ersatz nur ein anderer DocumentType, Comment- oder ProcessingInstruction-Knoten sinnvoll. Alles andere führt zu einem HierarchyRequestError.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $...nodes | Node | string | Beliebig viele Knoten oder Zeichenketten, die an die Stelle des Doctypes treten. Zeichenketten werden zu Text-Knoten und sind deshalb direkt unter einem Document nicht erlaubt. Ohne Argumente wird der Doctype einfach entfernt, genau wie mit remove(). |
Rückgabewert
undefined zurück. Die Änderung wirkt direkt auf den DOM-Baum.Beispiele
Doctype des aktuellen Dokuments durch einen neuen ersetzen
const oldDoctype = document.doctype;
if (oldDoctype) {
// Einfachen HTML5-Doctype erzeugen
const html5 = document.implementation.createDocumentType('html', '', '');
oldDoctype.replaceWith(html5);
}
console.log(document.doctype.name, JSON.stringify(document.doctype.publicId));
DTD-Referenz in einem XML-Dokument aktualisieren
const source = '<!DOCTYPE note SYSTEM "note.dtd"><note><to>Anna</to></note>';
const xml = new DOMParser().parseFromString(source, 'application/xml');
const newDoctype = xml.implementation.createDocumentType('note', '', 'note-v2.dtd');
xml.doctype.replaceWith(newDoctype);
console.log(new XMLSerializer().serializeToString(xml));
Doctype durch einen Kommentar ersetzen und Fehlerfall abfangen
const xml = new DOMParser().parseFromString(
'<!DOCTYPE config SYSTEM "config.dtd"><config/>',
'application/xml'
);
// Ein Kommentar ist als Kind von Document erlaubt
xml.doctype.replaceWith(xml.createComment(' DTD entfernt '));
console.log(xml.doctype); // kein Doctype mehr vorhanden
console.log(new XMLSerializer().serializeToString(xml));
// Ein String würde zu einem Text-Knoten werden und ist deshalb nicht erlaubt
const doc2 = new DOMParser().parseFromString('<!DOCTYPE a><a/>', 'application/xml');
try {
doc2.doctype.replaceWith('Hallo');
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
- Doctype kann
nullsein: Hat das Dokument keinen Doctype, liefertdocument.doctypeden Wertnull. Prüfe das vor dem Aufruf oder verwendedocument.doctype?.replaceWith(...). - HierarchyRequestError: Diesen Fehler gibt es bei Zeichenketten und Text-Knoten, bei Elementen, wenn schon ein Wurzelelement existiert, bei einem zweiten Doctype und wenn ein Doctype hinter dem Wurzelelement landen würde.
- Kein Einfluss auf den Rendermodus: Ob ein HTML-Dokument im Quirks- oder Standardmodus dargestellt wird, legt der Browser beim Parsen fest. Wenn du den Doctype später änderst, bleibt
document.compatModegleich. - Ist der Doctype an keinen Elternknoten angehängt, macht der Aufruf nichts.
- Kompatibilität: Die Methode wird von allen modernen Browsern unterstützt, aber nicht vom Internet Explorer. Dort bleibt nur
parentNode.replaceChild().