Signatur
Beschreibung
setBaseAndExtent() legt die Textauswahl des Dokuments in einem Schritt neu fest. Du übergibst zwei Randpunkte, jeweils als Knoten mit Offset: den Anker (Startpunkt der Auswahl) und den Fokus (Endpunkt, an dem der Cursor steht). Eine vorhandene Auswahl wird dabei vollständig ersetzt. Vorher removeAllRanges() aufzurufen ist nicht nötig.
Welche Bedeutung der Offset hat, hängt vom Knotentyp ab. Bei Textknoten (und Comment/CDATASection) zählt er die Zeichen, genauer gesagt UTF-16-Codeeinheiten. Bei Elementknoten zählt er die Kindknoten. setBaseAndExtent(p, 0, p, p.childNodes.length) wählt also den gesamten Inhalt von p aus.
Anders als bei Range und addRange() darf der Fokus im Dokument vor dem Anker liegen. Dann entsteht eine rückwärts gerichtete Auswahl, so als hätte man mit der Maus von rechts nach links gezogen. Das wirkt sich auf das Verhalten aus, wenn danach die Umschalttaste und eine Pfeiltaste gedrückt werden oder Selection.extend() aufgerufen wird. Die Methode eignet sich deshalb für Editoren, Funktionen zum Hervorheben von Suchtreffern, „Alles markieren“-Schaltflächen und für Tests, die Auswahlen simulieren.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $anchorNode Pflicht | Node | Knoten, in dem die Auswahl beginnt (Anker). | |
| $anchorOffset Pflicht | number | Position innerhalb von anchorNode: bei Textknoten die Zahl der Zeichen, bei Elementen die Zahl der Kindknoten vor dem Startpunkt. |
|
| $focusNode Pflicht | Node | Knoten, in dem die Auswahl endet (Fokus). Er darf im Dokument vor dem Anker liegen. | |
| $focusOffset Pflicht | number | Position innerhalb von focusNode, gezählt wie bei anchorOffset. |
Beispiele
Gesamten Inhalt eines Absatzes markieren
const p = document.querySelector('#intro');
const selection = window.getSelection();
// Offsets zählen hier Kindknoten, weil p ein Element ist
selection.setBaseAndExtent(p, 0, p, p.childNodes.length);
console.log(selection.toString());
Teil eines Textknotens auswählen
// <p id="satz">Hallo schöne Welt</p>
const text = document.querySelector('#satz').firstChild; // Textknoten
const sel = document.getSelection();
// Zeichen 6 bis 12 → "schöne"
sel.setBaseAndExtent(text, 6, text, 12);
console.log(sel.toString());
console.log(sel.anchorOffset, sel.focusOffset);
Rückwärts gerichtete Auswahl über zwei Elemente
// <p id="a">Erster Absatz</p><p id="b">Zweiter Absatz</p>
const a = document.querySelector('#a').firstChild;
const b = document.querySelector('#b').firstChild;
const sel = getSelection();
// Anker am Ende von #b, Fokus am Anfang von #a
sel.setBaseAndExtent(b, b.length, a, 0);
console.log(sel.direction ?? 'direction nicht unterstützt');
console.log(sel.getRangeAt(0).startContainer === a);
Suchtreffer markieren und in den sichtbaren Bereich scrollen
const markiereTreffer = (container, begriff) => {
const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT);
for (let node = walker.nextNode(); node; node = walker.nextNode()) {
const index = node.data.indexOf(begriff);
if (index !== -1) {
getSelection().setBaseAndExtent(node, index, node, index + begriff.length);
node.parentElement.scrollIntoView({ block: 'center' });
return true;
}
}
return false;
};
console.log(markiereTreffer(document.body, 'JavaScript'));
// Wichtig · Fallstricke
- Ein Offset, der größer ist als die Länge des Knotens (Zeichen bzw.
childNodes.length), löst eineIndexSizeError-DOMExceptionaus. - Knoten, die zu einem anderen Dokument gehören, werden ignoriert. Knoten, die mit dem Dokument nicht verbunden sind, können je nach Browser zu einer leeren Auswahl führen.
- Ein
DocumentType-Knoten als Anker oder Fokus führt zu einemInvalidNodeTypeError. - Die Offsets zählen UTF-16-Codeeinheiten. Emojis und andere Zeichen außerhalb der BMP belegen jeweils zwei Einheiten. Wählst du nur eine davon aus, wird das Zeichen zerteilt.
- Die Methode wirkt nicht auf den Text in
<input>- oder<textarea>-Feldern. Dafür gibt essetSelectionRange(). - Nach dem Aufruf wird asynchron das Ereignis
selectionchangeausgelöst. Die EigenschaftSelection.directionist neuer und wird noch nicht von allen Browsern unterstützt.setBaseAndExtent()selbst funktioniert in allen modernen Browsern. - Innerhalb eines Shadow DOM verhalten sich Auswahlen je nach Browser unterschiedlich. Erwäge dort
getComposedRanges().