Signatur
Beschreibung
Die Methode getSVGDocument() des Interfaces HTMLObjectElement liefert das Dokument, das in einem <object>-Element geladen wurde, zum Beispiel eine externe SVG-Datei. So lassen sich einzelne Elemente der Grafik per Skript auslesen, verändern oder mit Ereignis-Handlern versehen. Das ist mit einem <img>-Element nicht möglich.
Das Ergebnis entspricht in der Praxis der Eigenschaft contentDocument. Moderne Browser geben das Dokument auch dann zurück, wenn es gar kein SVG ist, etwa bei einer eingebetteten HTML-Seite. Die Methode stammt aus der älteren SVG-1.1-Spezifikation. Für neuen Code ist contentDocument die übliche und besser standardisierte Wahl.
Wichtig ist der richtige Zeitpunkt: Das eingebettete Dokument wird asynchron geladen. Deshalb sollte man die Methode erst im load-Ereignis des <object>-Elements aufrufen. Vorher bekommt man meist null oder ein leeres Dokument (about:blank) zurück.
Rückgabewert
Document (bei SVG in der Regel ein XMLDocument mit <svg> als documentElement) der eingebetteten Ressource. null, wenn noch nichts geladen ist, das Laden fehlgeschlagen ist oder das Dokument von einer anderen Herkunft (Origin) stammt.Beispiele
SVG nach dem Laden auslesen
// HTML: <object id="logo" type="image/svg+xml" data="logo.svg"></object>
const obj = document.getElementById('logo');
obj.addEventListener('load', () => {
const svgDoc = obj.getSVGDocument();
if (!svgDoc) {
console.warn('SVG nicht zugänglich (Cross-Origin oder Ladefehler)');
return;
}
const root = svgDoc.documentElement;
console.log(root.nodeName, root.getAttribute('viewBox'));
});
Farben einer eingebetteten Karte per Skript ändern
// HTML: <object id="karte" type="image/svg+xml" data="deutschland.svg"></object>
const karte = document.getElementById('karte');
const faerbeRegionen = (werte) => {
const svgDoc = karte.getSVGDocument();
if (!svgDoc) return;
for (const [id, farbe] of Object.entries(werte)) {
const region = svgDoc.getElementById(id);
if (region) region.setAttribute('fill', farbe);
}
};
karte.addEventListener('load', () => {
faerbeRegionen({ bayern: '#1e88e5', berlin: '#e53935' });
});
Klicks innerhalb des SVG abfangen
const obj = document.querySelector('object[data="schaltplan.svg"]');
obj.addEventListener('load', () => {
const svgDoc = obj.getSVGDocument() ?? obj.contentDocument;
svgDoc?.addEventListener('click', (event) => {
const id = event.target.closest('[id]')?.id;
console.log('Geklickt:', id);
});
});
Promise-Helfer mit Zeitgrenze
const ladeSVGDokument = (obj, timeout = 5000) =>
new Promise((resolve, reject) => {
const doc = obj.getSVGDocument();
if (doc?.documentElement?.nodeName === 'svg') return resolve(doc);
const timer = setTimeout(() => reject(new Error('Zeitüberschreitung')), timeout);
obj.addEventListener('load', () => {
clearTimeout(timer);
const geladen = obj.getSVGDocument();
geladen ? resolve(geladen) : reject(new Error('Kein Zugriff'));
}, { once: true });
});
const svgDoc = await ladeSVGDokument(document.querySelector('#logo'));
console.log(svgDoc.querySelectorAll('path').length);
// Wichtig · Fallstricke
- Same-Origin-Policy: Stammt die SVG-Datei von einer anderen Herkunft (Origin), gibt die Methode
nullzurück. CORS-Header helfen hier nicht. Die Datei muss von derselben Herkunft ausgeliefert werden. - Zeitpunkt: Vor dem
load-Ereignis bekommt mannulloder ein leeres Dokument (about:blank). ImDOMContentLoaded-Ereignis der Hauptseite ist das SVG meist noch nicht geladen. - Lokale Dateien: Bei Seiten, die über
file://geöffnet werden, blockieren viele Browser (z. B. Chrome) den Zugriff. Zum Testen einen lokalen Webserver verwenden. - Legacy-API: Die Methode stammt aus der älteren SVG-1.1-Spezifikation. Empfohlen ist die Eigenschaft
contentDocument, die gleichwertig ist und auch bei<iframe>funktioniert.getSVGDocument()gibt es auch beiHTMLEmbedElementundHTMLIFrameElement. - Sicherheit: Eingebettete SVG-Dateien können eigene Skripte enthalten. SVG-Dateien, die Nutzer hochgeladen haben, sollten nie von derselben Herkunft wie die Anwendung ausgeliefert werden, weil sonst XSS möglich ist. Soll die Grafik nur angezeigt werden, ist
<img>sicherer, denn dort werden keine Skripte ausgeführt. - Für einfache Änderungen der Darstellung ist Inline-SVG oft die bessere Lösung: Es lässt sich direkt über das DOM der Hauptseite und per CSS ansprechen.