Start · Sprachen · JavaScript · Referenz · Range.selectNodeContents()

Range.selectNodeContents()

Methode

Setzt Start und Ende des Range so, dass er den gesamten Inhalt des angegebenen Knotens umfasst, den Knoten selbst aber nicht.

seit JavaScript Baseline: alle Browser (DOM Level 2) Kategorie: webapi

Signatur

Range.prototype.selectNodeContents(referenceNode)

Beschreibung

selectNodeContents() setzt einen Range auf den Inhalt eines Knotens. Der Startpunkt liegt danach bei (referenceNode, 0), der Endpunkt bei (referenceNode, länge). Die Länge ist bei Element- und Dokumentknoten die Anzahl der Kindknoten (childNodes.length), bei Text-, Kommentar- und CDATASection-Knoten die Zeichenanzahl (length).

Im Unterschied zu selectNode() gehört der Knoten selbst nicht zum Bereich, nur seine Kinder bzw. sein Text. Das ist praktisch, wenn Sie den Text eines Elements markieren wollen (etwa für eine „Alles kopieren“-Funktion), den Inhalt eines Containers mit extractContents() herauslösen oder mit deleteContents() leeren möchten. Außerdem können Sie damit Inhalte mit surroundContents() umschließen oder die Abmessungen von Text mit getBoundingClientRect() messen.

Zusammen mit window.getSelection() und Selection.addRange() ist die Methode der übliche Weg, den Inhalt eines Elements für den Nutzer sichtbar zu markieren.

Parameter

Name Typ Default Beschreibung
$referenceNode Pflicht Node Der Knoten, dessen Inhalt der Range umfassen soll. Das kann ein Element, ein Textknoten, ein Document, ein DocumentFragment usw. sein.

Beispiele

Inhalt eines Elements für den Nutzer markieren

const markiereInhalt = (element) => {
  const range = document.createRange();
  range.selectNodeContents(element);

  const selection = window.getSelection();
  selection.removeAllRanges();
  selection.addRange(range);
};

// z. B. Codeblock per Doppelklick komplett markieren
document.querySelector('pre').addEventListener('dblclick', (e) => {
  markiereInhalt(e.currentTarget);
  console.log(window.getSelection().toString().length > 0);
});
true

Start- und Endpunkt prüfen

const p = document.createElement('p');
p.innerHTML = 'Hallo <b>Welt</b>!';

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

console.log(range.startContainer === p, range.startOffset);
console.log(range.endContainer === p, range.endOffset);
console.log(range.toString());

// Bei einem Textknoten zählt der Offset Zeichen
range.selectNodeContents(p.firstChild);
console.log(range.endOffset);
true 0 true 3 Hallo Welt! 6

Inhalt in ein Fragment verschieben

const quelle = document.createElement('div');
quelle.innerHTML = '<li>Eins</li><li>Zwei</li>';
const ziel = document.createElement('ul');

const range = document.createRange();
range.selectNodeContents(quelle);
const fragment = range.extractContents(); // Quelle ist danach leer
ziel.append(fragment);

console.log(quelle.childNodes.length, ziel.children.length);
0 2

Textbreite messen

const span = document.createElement('span');
span.textContent = 'Wie breit bin ich?';
document.body.append(span);

const range = document.createRange();
range.selectNodeContents(span);
const { width } = range.getBoundingClientRect();
console.log(`Breite: ${Math.round(width)}px`);
Breite: 123px (abhängig von Schrift)

// Wichtig · Fallstricke

  • Nicht mit selectNode() verwechseln: selectNodeContents() lässt den Knoten selbst aus dem Bereich heraus. Daher entfernt deleteContents() danach nur die Kinder, das Element selbst bleibt stehen.
  • Ist referenceNode ein DocumentType-Knoten (Doctype), wird ein InvalidNodeTypeError (DOMException) ausgelöst. Ohne Argument gibt es einen TypeError.
  • Der Range ist „live“: Ändert sich später der DOM, werden die Grenzpunkte angepasst. Wenn Kinder nachträglich angehängt werden, gehören sie aber nicht automatisch zum Bereich, denn der Endoffset bleibt unter Umständen beim alten Wert.
  • In <input>- und <textarea>-Elementen funktioniert das Markieren so nicht, weil ihr Text nicht als Kindknoten im DOM liegt. Nutzen Sie dort element.select() bzw. setSelectionRange().
  • Die Methode wird von allen modernen Browsern und seit IE9 unterstützt.