Signatur
Beschreibung
Selection.focusNode gibt den Knoten zurück, in dem der Fokus der Auswahl liegt. Der Fokus ist das Ende, das beim Markieren „bewegt“ wird. Das Gegenstück ist der Anker (anchorNode), also der Punkt, an dem das Markieren begonnen hat. Zusammen mit focusOffset lässt sich die Endposition genau bestimmen.
Wichtig: Der Fokus liegt nicht zwingend hinter dem Anker im Dokument. Wer von rechts nach links oder von unten nach oben markiert, erzeugt eine „rückwärts“ gerichtete Auswahl. Dann steht focusNode im Dokument vor anchorNode. Wenn du die Auswahl unabhängig von der Richtung brauchst, nimm getRangeAt(0) und dort startContainer bzw. endContainer.
Meist ist focusNode ein Textknoten (Text). Dann zählt focusOffset Zeichen. Ist es ein Elementknoten, zählt focusOffset Kindknoten. Gibt es keine Auswahl (rangeCount === 0), ist der Wert null.
Typische Einsatzfälle sind Editoren mit contenteditable, Werkzeugleisten für markierten Text, die Richtung einer Auswahl erkennen oder die Cursorposition merken und später wiederherstellen.
Rückgabewert
Text-Knoten), oder null, wenn es keine Auswahl gibt.Beispiele
Anfang und Ende der Auswahl ausgeben
document.addEventListener('selectionchange', () => {
const sel = document.getSelection();
if (!sel || !sel.focusNode) return;
console.log('Anker:', sel.anchorNode.nodeName, sel.anchorOffset);
console.log('Fokus:', sel.focusNode.nodeName, sel.focusOffset);
});
Auswahlrichtung erkennen (vorwärts/rückwärts)
const isBackward = (sel) => {
if (!sel.anchorNode || !sel.focusNode) return false;
if (sel.anchorNode === sel.focusNode) {
return sel.focusOffset < sel.anchorOffset;
}
const pos = sel.anchorNode.compareDocumentPosition(sel.focusNode);
return Boolean(pos & Node.DOCUMENT_POSITION_PRECEDING);
};
document.addEventListener('mouseup', () => {
const sel = window.getSelection();
console.log(isBackward(sel) ? 'rückwärts markiert' : 'vorwärts markiert');
});
Element am Cursor in einem contenteditable-Editor finden
const editor = document.querySelector('#editor');
const currentBlock = () => {
const { focusNode } = document.getSelection();
if (!focusNode || !editor.contains(focusNode)) return null;
// Textknoten haben kein closest() – daher zum Elternelement wechseln
const el = focusNode.nodeType === Node.TEXT_NODE ? focusNode.parentElement : focusNode;
return el.closest('p, h1, h2, h3, li');
};
editor.addEventListener('keyup', () => {
console.log('Cursor in:', currentBlock()?.tagName);
});
Auswahl bis zum Ende eines Absatzes erweitern
const sel = window.getSelection();
const para = document.querySelector('p');
if (sel.rangeCount > 0) {
// extend() verschiebt nur den Fokus, der Anker bleibt
sel.extend(para, para.childNodes.length);
console.log(sel.focusNode === para, sel.focusOffset);
}
// Wichtig · Fallstricke
- Richtung beachten:
focusNodeist nicht unbedingt das Ende im Dokument. Wenn die Richtung egal sein soll, nutzegetRangeAt(0).endContainer. - Offset-Bedeutung: Bei Textknoten zählt
focusOffsetZeichen (UTF-16-Einheiten), bei Elementknoten zählt es Kindknoten. - Textknoten:
focusNodeist oft einText-Knoten. Methoden wieclosest()oderclassListgibt es dort nicht. Wechsle vorher überparentElementzum Element. - Formularfelder: In
<input>und<textarea>zeigtfocusNodenicht auf den Text im Feld. Dort nutzt duselectionStart/selectionEnd. - Shadow DOM: Liegt die Auswahl in einem Shadow Root, liefert
document.getSelection()je nach Browser den Host-Knoten. Neuere Browser bieten dafürgetComposedRanges()an. - Kompatibilität: Wird von allen modernen Browsern unterstützt. Ohne Auswahl ist der Wert
null, also vor dem Zugriff prüfen.