Signatur
Beschreibung
SVGTextContentElement ist ein abstraktes Interface. Es wird von allen SVG-Elementen implementiert, die Kind-Textinhalte rendern, also von SVGTextElement, SVGTSpanElement und SVGTextPathElement. Direkt instanziieren kann man es nicht. Man erhält es über document.createElementNS() oder über einen DOM-Zugriff auf ein vorhandenes Textelement.
Das Interface ist vor allem zum Vermessen von Text gedacht. Damit lassen sich Beschriftungen in Diagrammen zentrieren, Text vor dem Rendern kürzen, Hintergrundboxen passgenau zeichnen oder Positionen einzelner Zeichen bestimmen, etwa für Animationen und Hervorhebungen.
- Eigenschaften:
textLength(SVGAnimatedLength, die gewünschte Textlänge),lengthAdjust(SVGAnimatedEnumeration:LENGTHADJUST_SPACING= 1 oderLENGTHADJUST_SPACINGANDGLYPHS= 2). - Methoden:
getNumberOfChars(),getComputedTextLength(),getSubStringLength(charnum, nchars),getStartPositionOfChar(charnum),getEndPositionOfChar(charnum),getExtentOfChar(charnum),getRotationOfChar(charnum),getCharNumAtPosition(point)undselectSubString(charnum, nchars)(veraltet).
Alle Messmethoden liefern Werte im Benutzerkoordinatensystem des Elements. Transformationen der Eltern-Elemente fließen also nicht ein. Außerdem geben sie nur dann sinnvolle Werte zurück, wenn das Element im Dokument hängt und gerendert wird.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $charnum Pflicht | number | Index des Zeichens (in UTF-16-Codeeinheiten), beginnend bei 0. Wird von getStartPositionOfChar(), getEndPositionOfChar(), getExtentOfChar(), getRotationOfChar() und getSubStringLength() verwendet. |
|
| $nchars Pflicht | number | Anzahl der Zeichen ab charnum, bei getSubStringLength() und selectSubString(). |
|
| $point Pflicht | DOMPointInit | Punkt im Benutzerkoordinatensystem für getCharNumAtPosition(). Zurückgegeben wird der Index des Zeichens an dieser Stelle oder -1, wenn dort kein Zeichen liegt. |
Rückgabewert
<text>-, <tspan>- und <textPath>-Elemente verfügbar. Die Messmethoden liefern number, DOMPoint oder DOMRect.Beispiele
Textelement erzeugen und Breite messen
const SVG_NS = 'http://www.w3.org/2000/svg';
const svg = document.createElementNS(SVG_NS, 'svg');
svg.setAttribute('width', '300');
svg.setAttribute('height', '60');
const text = document.createElementNS(SVG_NS, 'text');
text.setAttribute('x', '10');
text.setAttribute('y', '35');
text.textContent = 'Umsatz 2024';
svg.append(text);
document.body.append(svg); // Messen funktioniert erst nach dem Einhängen
console.log(text instanceof SVGTextContentElement);
console.log('Zeichen:', text.getNumberOfChars());
console.log('Breite:', text.getComputedTextLength().toFixed(1));
Beschriftung zu lang? Mit Auslassungszeichen kürzen
const truncateLabel = (textEl, maxWidth) => {
const original = textEl.textContent;
if (textEl.getComputedTextLength() <= maxWidth) return;
let len = original.length;
while (len > 0) {
textEl.textContent = original.slice(0, len) + '…';
if (textEl.getComputedTextLength() <= maxWidth) break;
len--;
}
textEl.setAttribute('title', original);
};
const label = document.querySelector('svg text.axis-label');
truncateLabel(label, 80);
console.log(label.textContent);
Hintergrundbox hinter ein Zeichen und textLength setzen
const text = document.querySelector('#headline'); // <text> im DOM
// Box um das dritte Zeichen zeichnen
const box = text.getExtentOfChar(2);
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
Object.entries({ x: box.x, y: box.y, width: box.width, height: box.height, fill: 'gold' })
.forEach(([k, v]) => rect.setAttribute(k, v));
text.before(rect);
// Text auf exakt 200 Einheiten strecken, nur über den Zeichenabstand
text.textLength.baseVal.value = 200;
text.lengthAdjust.baseVal = SVGTextContentElement.LENGTHADJUST_SPACING;
console.log(text.getComputedTextLength());
Welches Zeichen wurde angeklickt?
const text = document.querySelector('svg text');
text.addEventListener('click', (event) => {
const svg = text.ownerSVGElement;
const pt = new DOMPoint(event.clientX, event.clientY)
.matrixTransform(text.getScreenCTM().inverse());
const index = text.getCharNumAtPosition(pt);
if (index >= 0) {
console.log(`Zeichen ${index}: "${text.textContent[index]}"`);
}
});
// Wichtig · Fallstricke
- Nicht gerendert heißt: keine Messwerte. Hängt das Element nicht im DOM oder ist es mit
display: noneausgeblendet, liefertgetComputedTextLength()in der Regel0. Die zeichenbezogenen Methoden können dann eineIndexSizeError-Ausnahme werfen. - Webfonts: Wer vor dem Laden der Schrift misst, bekommt falsche Werte. Vorher mit
await document.fonts.readyauf die Schrift warten. - Zeichenindizes zählen UTF-16-Codeeinheiten. Emojis und Zeichen außerhalb der BMP (Basic Multilingual Plane) belegen je nach Browser zwei Indizes. Ein ungültiger
charnumwirftIndexSizeError. - Koordinaten: Die Ergebnisse gelten im lokalen Benutzerkoordinatensystem. Für Bildschirmkoordinaten muss man mit
getScreenCTM()umrechnen. - Performance: Jede Messung kann ein synchrones Layout erzwingen. In Schleifen sollte man Schreib- und Lesezugriffe daher bündeln.
selectSubString()ist veraltet und wird nicht zuverlässig unterstützt. Stattdessen die Selection-API verwenden.- Browser-Kompatibilität: Die Kernmethoden werden von allen modernen Browsern unterstützt.
getCharNumAtPosition()akzeptiert in neueren Browsern einDOMPointInit, ältere erwarteten einSVGPointaussvg.createSVGPoint().