Start · Sprachen · JavaScript · Referenz · SVGForeignObjectElement

SVGForeignObjectElement

Schnittstelle

Repräsentiert ein <code>&lt;foreignObject&gt;</code>-Element, mit dem sich fremde XML-Inhalte (meist HTML) in eine SVG-Grafik einbetten lassen.

seit JavaScript Baseline: alle Browser (SVG 1.1) Kategorie: webapi

Signatur

interface SVGForeignObjectElement extends SVGGraphicsElement

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 (Attribut x)
  • y – y-Koordinate der oberen linken Ecke (Attribut y)
  • width – Breite des Bereichs (Attribut width)
  • height – Höhe des Bereichs (Attribut height)

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

Typ
SVGForeignObjectElement
Beschreibung
Mit 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);
true

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'));
20 200 400 50%

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 kein SVGForeignObjectElement. Nimm immer createElementNS() 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 width oder height (Standard 0 bzw. 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ägt toDataURL() fehl, was in älteren Safari-Versionen häufig war.
  • Sicherheit: Wird fremdes Markup über innerHTML in ein foreignObject geschrieben, gelten dieselben XSS-Risiken wie bei normalem HTML. Nutzereingaben also bereinigen, z. B. mit DOMPurify oder der Sanitizer-API, oder textContent verwenden.
  • Kompatibilität: Wird von allen modernen Browsern unterstützt. Transformationen und clip-path auf foreignObject werden in WebKit teilweise fehlerhaft dargestellt. Ein Internet Explorer unterstützte foreignObject gar nicht.