Start · Sprachen · JavaScript · Referenz · SVGTextContentElement.getNumberOfChars()

SVGTextContentElement.getNumberOfChars()

Methode

Gibt die Gesamtzahl der adressierbaren Zeichen in einem SVG-Textelement zurück, egal ob diese Zeichen tatsächlich gerendert werden.

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

Signatur

SVGTextContentElement.prototype.getNumberOfChars()

Beschreibung

Die Methode getNumberOfChars() gibt es auf allen Elementen, die von SVGTextContentElement erben, also auf <text>, <tspan> und <textPath>. Sie gibt zurück, wie viele adressierbare Zeichen das Element enthält, einschließlich der Zeichen in verschachtelten <tspan>-Kindelementen.

„Adressierbar“ heißt: Gezählt werden die Zeichen, auf die man über einen Index mit Methoden wie getStartPositionOfChar(), getExtentOfChar(), getRotationOfChar() oder getSubStringLength() zugreifen kann. Die Zählung erfolgt in UTF-16-Code-Einheiten, genauso wie bei String.prototype.length. Zeichen, die zum Beispiel wegen Überlaufs nicht sichtbar sind, zählen trotzdem mit.

Die Methode wird vor allem als Obergrenze für Schleifen über die zeichenbezogenen Geometrie-Methoden genutzt, etwa um einzelne Buchstaben zu animieren, Zeichen hervorzuheben, Text mit Auslassungspunkten zu kürzen oder Treffer beim Anklicken zu bestimmen (in Kombination mit getCharNumAtPosition()).

Beispiele

Zeichen in einem Textelement zählen

// HTML: <svg><text id="titel" x="10" y="30">Hallo <tspan fill="red">SVG</tspan></text></svg>
const text = document.getElementById('titel');

console.log(text.getNumberOfChars());
console.log(text.querySelector('tspan').getNumberOfChars());
9 3

Einzelne Zeichen mit Rechtecken markieren

const svgNS = 'http://www.w3.org/2000/svg';
const text = document.querySelector('svg text');
const svg = text.ownerSVGElement;

const anzahl = text.getNumberOfChars();
for (let i = 0; i < anzahl; i++) {
  const box = text.getExtentOfChar(i); // DOMRect des Zeichens
  const rect = document.createElementNS(svgNS, 'rect');
  rect.setAttribute('x', box.x);
  rect.setAttribute('y', box.y);
  rect.setAttribute('width', box.width);
  rect.setAttribute('height', box.height);
  rect.setAttribute('fill', 'none');
  rect.setAttribute('stroke', i % 2 ? 'steelblue' : 'orange');
  svg.insertBefore(rect, text);
}

Text auf maximale Breite kürzen (Auslassungspunkte)

const kuerzeText = (textEl, maxBreite) => {
  const original = textEl.textContent;
  if (textEl.getComputedTextLength() <= maxBreite) return;

  let n = textEl.getNumberOfChars();
  // so lange Zeichen entfernen, bis Text + „…“ passt
  while (n > 0) {
    textEl.textContent = original.slice(0, --n) + '…';
    if (textEl.getComputedTextLength() <= maxBreite) break;
  }
};

kuerzeText(document.querySelector('#label'), 120);

Emoji: Zählung in UTF-16-Einheiten

// <text id="emo" x="0" y="20">Hi 👋</text>
const emo = document.getElementById('emo');
console.log(emo.getNumberOfChars());
console.log([...emo.textContent].length); // Codepoints
5 4

// Wichtig · Fallstricke

  • UTF-16-Zählung: Zeichen außerhalb der Basic Multilingual Plane, etwa Emoji oder manche CJK-Zeichen, zählen als 2. Bei Schleifen mit getExtentOfChar() können deshalb Indizes auf die zweite Hälfte eines Surrogatpaars zeigen. Graphem-Cluster (z. B. 👨‍👩‍👧) belegen noch mehr Einheiten.
  • Leerraum: Wie Leerzeichen, Zeilenumbrüche und xml:space bzw. white-space verarbeitet werden, beeinflusst das Ergebnis. Der Wert kann darum von textContent.length abweichen, und ältere Browser haben zusammengefallenen Leerraum teils unterschiedlich gezählt.
  • Die geometrischen Nachbar-Methoden (getExtentOfChar() usw.) brauchen ein gerendertes Element. Bei display: none oder einem Element, das nicht im Dokument hängt, liefern sie Nullwerte oder werfen Fehler. getNumberOfChars() selbst ist davon meist nicht betroffen.
  • Indizes ab getNumberOfChars() lösen bei den zeichenbezogenen Methoden einen IndexSizeError (DOMException) aus.
  • Die Methode wird in allen modernen Browsern seit Langem unterstützt.