Start · Sprachen · JavaScript · Referenz · AbstractRange.endContainer

AbstractRange.endContainer

Eigenschaft

Schreibgeschützte Eigenschaft, die den <code>Node</code> liefert, in dem das Ende eines Bereichs (<code>Range</code> oder <code>StaticRange</code>) liegt.

seit JavaScript Baseline: alle modernen Browser (AbstractRange sei Kategorie: webapi

Signatur

AbstractRange.endContainer

Beschreibung

endContainer ist eine schreibgeschützte Eigenschaft des Interfaces AbstractRange. Sie gibt den Knoten zurück, in dem der Endpunkt eines Bereichs liegt. Zusammen mit endOffset legt sie die Endposition eindeutig fest. Die Eigenschaft wird an Range (lebendiger Bereich) und StaticRange (unveränderlicher Schnappschuss) vererbt.

Wie endOffset zu lesen ist, hängt vom Knotentyp ab:

  • Bei Text-, Comment- oder CDATASection-Knoten ist endOffset ein Zeichenindex innerhalb der Zeichenkette.
  • Bei allen anderen Knoten (z. B. Elementen) ist endOffset der Index eines Kindknotens in childNodes.

Gebraucht wird die Eigenschaft vor allem bei Texteditoren, beim Auswerten der Benutzerauswahl (Selection.getRangeAt()), beim Hervorheben von Text und beim Auswerten von InputEvent.getTargetRanges(), die StaticRange-Objekte liefert.

Setzen lässt sich der Wert nicht direkt. Bei einem Range geht das über setEnd(), setEndBefore(), setEndAfter() oder selectNodeContents(). Bei einem StaticRange wird er einmal im Konstruktor festgelegt.

Rückgabewert

Typ
Node
Beschreibung
Der Knoten, in dem der Bereich endet, oft ein Text-Knoten oder ein Element. Bei einem neuen, leeren Range ist es das Document.

Beispiele

Endcontainer eines Range ermitteln

const p = document.createElement('p');
p.textContent = 'Hallo Welt';
document.body.append(p);

const range = document.createRange();
const text = p.firstChild; // Text-Knoten
range.setStart(text, 0);
range.setEnd(text, 5);

console.log(range.endContainer === text); // true
console.log(range.endContainer.nodeName);
console.log(range.endOffset);
console.log(range.toString());
true #text 5 Hallo

Wo endet die Benutzerauswahl?

document.addEventListener('selectionchange', () => {
  const selection = document.getSelection();
  if (!selection || selection.rangeCount === 0) return;

  const range = selection.getRangeAt(0);
  const end = range.endContainer;
  // Bei Text-Knoten das umgebende Element ermitteln
  const element = end.nodeType === Node.TEXT_NODE ? end.parentElement : end;

  console.log(`Auswahl endet in <${element?.tagName.toLowerCase()}> bei Offset ${range.endOffset}`);
});
Auswahl endet in <p> bei Offset 5

Element als Endcontainer: Offset zählt Kindknoten

const list = document.createElement('ul');
list.innerHTML = '<li>Eins</li><li>Zwei</li><li>Drei</li>';
document.body.append(list);

const range = document.createRange();
range.selectNodeContents(list);

console.log(range.endContainer === list); // true
console.log(range.endOffset); // Anzahl der Kindknoten
true 3

StaticRange aus beforeinput auswerten

const editor = document.querySelector('[contenteditable]');

editor.addEventListener('beforeinput', (event) => {
  for (const staticRange of event.getTargetRanges()) {
    console.log('Ende in:', staticRange.endContainer.nodeName,
                'Offset:', staticRange.endOffset);
  }
});
Ende in: #text Offset: 12

// Wichtig · Fallstricke

  • Schreibgeschützt: Eine Zuweisung an endContainer hat keine Wirkung (im Strict Mode gibt es einen TypeError). Das Ende eines Range setzt man mit setEnd() und verwandten Methoden.
  • Offset-Bedeutung prüfen: Vor dem Auswerten von endOffset immer endContainer.nodeType abfragen. Sonst verwechselt man leicht Zeichenindex und Kindindex.
  • Range vs. StaticRange: Ein Range passt sich an, wenn sich das DOM ändert. endContainer kann danach also auf einen anderen Knoten zeigen. Ein StaticRange wird nicht angepasst und kann nach DOM-Änderungen auf entfernte Knoten oder ungültige Offsets zeigen.
  • Bei einem eingeklappten Bereich (collapsed === true) gilt endContainer === startContainer.
  • Der endContainer muss nicht derselbe Knoten sein wie startContainer. Den gemeinsamen Vorfahren liefert Range.commonAncestorContainer.
  • Kompatibilität: Range.endContainer gibt es in allen Browsern schon lange. Das Basis-Interface AbstractRange und StaticRange sind erst seit etwa 2020 in allen modernen Browsern verfügbar.