Signatur
Beschreibung
Die Schnittstelle SVGForeignObjectElement steht für das SVG-Element <foreignObject>. Damit lassen sich Inhalte aus einem anderen XML-Namensraum, in der Praxis fast immer XHTML, in eine SVG-Grafik einbetten. Typische Fälle sind Textblöcke mit automatischem Zeilenumbruch, Formularfelder oder formatierte HTML-Beschriftungen in Diagrammen. Das braucht man, weil SVG-<text> selbst keinen Zeilenumbruch kennt.
Die Schnittstelle erbt von SVGGraphicsElement und damit auch Methoden wie getBBox(), getCTM() und getScreenCTM(). Dazu kommen vier eigene, schreibgeschützte Eigenschaften vom Typ SVGAnimatedLength:
x– x-Koordinate der oberen linken Ecke (Attributx)y– y-Koordinate der oberen linken Ecke (Attributy)width– Breite des Bereichs (Attributwidth)height– Höhe des Bereichs (Attributheight)
Die Eigenschaften selbst kann man nicht überschreiben. Werte setzt man über .baseVal.value bzw. .baseVal.newValueSpecifiedUnits() oder direkt mit setAttribute(). Den aktuellen, eventuell animierten Wert liefert .animVal. Die Schnittstelle hat keinen öffentlichen Konstruktor. Instanzen erzeugt man mit document.createElementNS("http://www.w3.org/2000/svg", "foreignObject").
Rückgabewert
createElementNS() im SVG-Namensraum erzeugte oder per DOM-Abfrage gefundene Instanz eines <foreignObject>-Elements.Beispiele
foreignObject dynamisch erzeugen und HTML einbetten
const SVG_NS = 'http://www.w3.org/2000/svg';
const XHTML_NS = 'http://www.w3.org/1999/xhtml';
const svg = document.createElementNS(SVG_NS, 'svg');
svg.setAttribute('width', '300');
svg.setAttribute('height', '150');
const fo = document.createElementNS(SVG_NS, 'foreignObject');
fo.setAttribute('x', '10');
fo.setAttribute('y', '10');
fo.setAttribute('width', '280');
fo.setAttribute('height', '130');
// HTML-Inhalt im XHTML-Namensraum
const div = document.createElementNS(XHTML_NS, 'div');
div.textContent = 'Dieser lange Text bricht automatisch um – anders als bei SVG-<text>.';
fo.append(div);
svg.append(fo);
document.body.append(svg);
console.log(fo instanceof SVGForeignObjectElement);
Geometrie über SVGAnimatedLength lesen und ändern
// <svg><foreignObject id="label" x="20" y="20" width="200" height="50">…</foreignObject></svg>
const label = document.querySelector('#label');
console.log(label.x.baseVal.value, label.width.baseVal.value);
// Breite verdoppeln
label.width.baseVal.value *= 2;
// Höhe in Prozent setzen (Einheitentyp 2 = SVG_LENGTHTYPE_PERCENTAGE)
label.height.baseVal.newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 50);
console.log(label.getAttribute('width'), label.getAttribute('height'));
Höhe automatisch an den HTML-Inhalt anpassen
const fitForeignObject = (fo) => {
const content = fo.firstElementChild;
if (!content) return;
// Tatsächliche Höhe des HTML-Inhalts messen
const { height } = content.getBoundingClientRect();
// Bildschirmpixel in Nutzerkoordinaten umrechnen
const scale = fo.getScreenCTM()?.d ?? 1;
fo.height.baseVal.value = Math.ceil(height / scale);
};
document.querySelectorAll('foreignObject').forEach(fitForeignObject);
// Wichtig · Fallstricke
- Namensraum beachten:
document.createElement('foreignObject')erzeugt ein unbekanntes HTML-Element und keinSVGForeignObjectElement. Nimm immercreateElementNS()mit dem SVG-Namensraum. Eingebettetes HTML gehört in den XHTML-Namensraum (http://www.w3.org/1999/xhtml), vor allem in eigenständigen SVG-Dateien. - Breite und Höhe sind Pflicht: Fehlen
widthoderheight(Standard0bzw.auto), ist der Inhalt je nach Browser unsichtbar. Überstehender Inhalt wird standardmäßig abgeschnitten. - Einschränkungen: In SVGs, die per
<img>oder als CSS-Hintergrund geladen werden, laufen keine Skripte und es werden keine externen Ressourcen geladen. Wird so ein SVG auf ein<canvas>gezeichnet, kann das Canvas je nach Browser als „tainted“ markiert werden. Dann schlägttoDataURL()fehl, was in älteren Safari-Versionen häufig war. - Sicherheit: Wird fremdes Markup über
innerHTMLin einforeignObjectgeschrieben, gelten dieselben XSS-Risiken wie bei normalem HTML. Nutzereingaben also bereinigen, z. B. mit DOMPurify oder der Sanitizer-API, odertextContentverwenden. - Kompatibilität: Wird von allen modernen Browsern unterstützt. Transformationen und
clip-pathaufforeignObjectwerden in WebKit teilweise fehlerhaft dargestellt. Ein Internet Explorer unterstützteforeignObjectgar nicht.