Start · Sprachen · JavaScript · Referenz · Selection.extend()

Selection.extend()

Methode

Verschiebt den Fokus (das bewegliche Ende) der aktuellen Auswahl an die angegebene Position, der Anker bleibt dabei unverändert.

seit JavaScript Baseline: alle modernen Browser Kategorie: webapi

Signatur

Selection.prototype.extend(node, offset)

Beschreibung

Selection.extend() verschiebt den Fokus einer bestehenden Auswahl, also das Ende, an dem der Nutzer die Auswahl gerade „zieht“, an einen neuen Punkt im Dokument. Der Anker (anchorNode/anchorOffset) bleibt stehen. Alles zwischen Anker und neuem Fokus ist danach ausgewählt. Das entspricht dem Verhalten von Shift+Klick oder Shift+Pfeiltaste.

Liegt der neue Fokus im Dokument vor dem Anker, wird die Auswahl rückwärts gerichtet. Die Richtung bleibt also erhalten, anders als bei einem Range, der immer vorwärts läuft. Genau deshalb braucht man extend(), wenn eine Auswahl per Skript gezielt nach vorn oder hinten wachsen oder schrumpfen soll, etwa in eigenen Editoren, bei Tastenkürzeln oder beim Nachbilden von Nutzeraktionen in Tests.

Wie offset zu verstehen ist, hängt vom Knotentyp ab. Bei Text-, Kommentar- und CDATA-Knoten zählt er Zeichen (UTF-16-Codeeinheiten). Bei Elementknoten zählt er Kindknoten. Vor dem Aufruf muss es eine Auswahl geben (rangeCount > 0), zum Beispiel über collapse() oder addRange().

Parameter

Name Typ Default Beschreibung
$node Pflicht Node Der Knoten, in dem der neue Fokus liegen soll.
$offset number 0 Position innerhalb von node: bei Textknoten der Zeichenindex, bei Elementen der Index des Kindknotens.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined). Die Methode ändert das Selection-Objekt direkt.

Beispiele

Auswahl vom Wortanfang aus erweitern

// <p id="text">Hallo schöne Welt</p>
const textNode = document.getElementById('text').firstChild;
const sel = window.getSelection();

// Anker auf Zeichen 6 setzen (vor "schöne")
sel.collapse(textNode, 6);
// Fokus auf Zeichen 12 verschieben
sel.extend(textNode, 12);

console.log(sel.toString());
console.log(sel.anchorOffset, sel.focusOffset);
schöne 6 12

Rückwärts gerichtete Auswahl erzeugen

const textNode = document.getElementById('text').firstChild; // "Hallo schöne Welt"
const sel = window.getSelection();

sel.collapse(textNode, 17); // Anker am Ende
sel.extend(textNode, 13);   // Fokus liegt vor dem Anker

console.log(sel.toString());
console.log(sel.direction ?? 'direction nicht unterstützt');
Welt backward

Shift+Pfeil nachbilden: Auswahl um ein Zeichen vergrößern

const growSelection = () => {
  const sel = window.getSelection();
  if (sel.rangeCount === 0 || !sel.focusNode) return;

  const { focusNode, focusOffset } = sel;
  if (focusNode.nodeType === Node.TEXT_NODE && focusOffset < focusNode.length) {
    sel.extend(focusNode, focusOffset + 1);
  }
};

document.addEventListener('keydown', (e) => {
  if (e.altKey && e.key === 'ArrowRight') {
    e.preventDefault();
    growSelection();
  }
});

Auswahl über mehrere Elemente ausdehnen

// <ul id="liste"><li>Eins</li><li>Zwei</li><li>Drei</li></ul>
const liste = document.getElementById('liste');
const sel = window.getSelection();

sel.collapse(liste, 0); // vor dem ersten <li>
sel.extend(liste, 2);   // nach dem zweiten <li>

console.log(sel.toString());
EinsZwei

// Wichtig · Fallstricke

  • Gibt es noch keine Auswahl (rangeCount === 0), wirft die Methode eine InvalidStateError-DOMException. Setzen Sie also vorher mit collapse() oder addRange() einen Anker.
  • Ist offset größer als die Länge des Knotens (Zeichen bzw. Anzahl der Kindknoten), wird eine IndexSizeError geworfen.
  • Liegt node in einem anderen Dokument oder ist er nicht mit dem Dokument verbunden, bleibt die Auswahl je nach Browser unverändert oder wird eingeklappt.
  • Der Offset zählt UTF-16-Codeeinheiten. Emojis und andere Zeichen außerhalb der BMP belegen zwei Positionen. Setzt man den Fokus mitten in ein solches Zeichen, entstehen kaputte Auswahlen.
  • Die Methode gab es früher nicht im Internet Explorer. Alle aktuellen Browser (Chrome, Firefox, Safari, Edge) unterstützen sie. Selection.direction zum Auslesen der Richtung ist neuer und nicht überall verfügbar.
  • In <input>- und <textarea>-Feldern wirkt extend() nicht. Dort nutzt man setSelectionRange() mit dem Parameter direction.