HTML5 und die Selection-API: Textauswahl und -bearbeitung mit JavaScript

Kein Beitragsbild

Denis Potschien

Denis Potschien ist seit 2005 freiberuflich als Kommunikationsdesigner tätig, seit Anfang 2010...

Per JavaScript die Textauswahl abzufragen, ist mit der Methode „getSelection()“ schon länger möglich. Die neue Selection-API erweitert diese Möglichkeit jedoch um einige neue Methoden und Eigenschaften, mit denen die Textauswahl bearbeitet und manipuliert werden kann. Es ist sogar machbar, mehr als einen Bereich eines Dokumentes auszuwählen – was ohne JavaScript nicht funktionieren würde.

selection-api

Auswahl erweitern und Cursor verschieben

Eine Funktion der Selection-API ist, eine Textauswahl zu erweitern oder die Position des Cursors zu verschieben. So ist es mit der Methode „modify()“ möglich, die Auswahl des Nutzers auf das nächste Zeichen, das nächste Wort, den nächsten Satz oder den gesamten Absatz zu erweitern. Die Methode erwartet drei Werte. Der erste gibt die Art der Veränderung an: „extend“ zum Erweitern der Auswahl und „move“ zum Verschieben des Textcursors.

Der zweite Wert gibt die Richtung an. Der Wert „forward“ verändert die Auswahl in Leserichtung, „backward“ verändert sie gegen die Leserichtung. Bei zB deutschen Texten wird bei „forward“ die Auswahl also nach rechts verändert. Bei zB arabischen Texten wird die Auswahl hingegen nach links verändert. Alternativ können auch die Werte „right“ und „left“ genutzt werden. Hier wird die Auswahl unabhängig der Leserichtung in die angegebene Richtung verändert.

Der letzte Wert gibt an, wohin die Auswahl erweitert beziehungsweise der Cursor verschoben werden soll. Möglich sind die Werte „character“, „word“, „line“, „sentence“ und „paragraph“, wobei Firefox die Werte „sentence“ und „paragraph“ nicht unterstützt.

document.addEventListener("click", function() {
  document.getSelection().modify("extend", "forward", "line");
}, false);

Im Beispiel wird eine Auswahl auf eine Zeile erweitert. Dabei erwartet die Methode nicht zwingend, dass ein Text ausgewählt wird, um ihn erweitern zu können. Es genügt, den Cursor an einer Stelle zu platzieren. Wird der Cursor am Zeilenanfang platziert, wird die gesamte Zeile ausgewählt. Wird der Cursor innerhalb der Zeile platziert, wird die Auswahl bis in die nächste Zeile erweitert, so dass die Auswahl immer eine Zeilenlänge lang ist. Damit JavaScript auf eine Cursorplatzierung reagieren kann, wird die Methode innerhalb eines „click“-Events ausgeführt.

selection-api_modify
Auf eine Zeile erweiterte Auswahl

Wird statt „extend“ der Wert „move“ gesetzt, so wird eine vorhandene Auswahl aufgehoben und der Cursor an die entsprechende Stelle verschoben.

Kennst du unser E-Book-Bundle? Spare jetzt 6,99 €!

E-Book Bundle von Andreas Hecht
document.addEventListener("click", function() {
  document.getSelection().modify("move", "forward", "sentence");
}, false);

Im Beispiel wird der Cursor beim Klick auf einen Text ans Satzende verschoben. Für die Angabe der Cursorposition gelten dieselben Schlüsselwörter wie bei „extend“. Die Cursorplatzierung funktioniert natürlich nur, wenn das Element bearbeitbar ist. Das trifft bei Eingabefeldern zu sowie bei Elementen, welche die Eigenschaft „contenteditable“ besitzen.

Mit der Methode „extend()“ ist es zudem möglich, eine Auswahl auf ein beliebiges Element zu erweitern. Die Methode erwartet zwei Parameter. Der erste gibt das Element an, auf welches die Auswahl erweitert werden soll. Der zweite Parameter gibt an, ob zum Anfang oder Ende des Elementes erweitert werden soll. Der Wert „1“ sorgt dafür, dass die Erweiterung zum Ende erfolgt.

document.addEventListener("click", function() {
  window.getSelection().extend(document.getElementsByTagName("p")[1], 1);
}, false);

Im Beispiel wird eine Auswahl immer zum Ende des zweiten „<p>“-Elements im Dokument erweitert. Wenn also im ersten „<p>“-Element ein Text ausgewählt oder der Cursor dort platziert wird, wird die Auswahl automatisch bis zum Ende des zweiten „<p>“-Elements erweitert. Soll die Erweiterung zum Anfang erfolgen, muss der zweite Parameter der Methode auf „0“ gesetzt werden.

selection-api_extend
Auswahl bis zum Ende des zweiten Absatzes erweitert

Mehrere Bereiche für eine Auswahl erstellen

Dass man zwei verschiedene Textstellen in einem Dokument auswählt, ist eigentlich nicht möglich. Das ist kein spezifisches Problem des Browsers, sondern grundsätzlich nicht vorgesehen. Dennoch gibt es mit der Selection-API genau diese Option, nämlich mehrere unterschiedliche Bereiche einer Auswahl hinzuzufügen – mit der „addRange()“-Methode.

Um einer Auswahl einen neuen Bereich hinzufügen zu können, muss mit „createRange()“ zunächst ein Bereich definiert werden. Diesem wird per „selectNode()“ ein vorhandener Elementknoten aus dem Dokument zugewiesen.

var auswahl = window.getSelection();
var bereich;

for (var i = 0; i < document.getElementsByTagName("strong").length; i++) {
  bereich = document.createRange();
  bereich.selectNode(document.getElementsByTagName("strong")[i]);
  auswahl.addRange(bereich);
}

Im Beispiel werden per „for“-Schleife  alle „<strong>“-Elemente der Auswahl hinzugefügt. Wird die Textauswahl kopiert und beispielsweise in einem Editor eingefügt, werden alle ausgewählten Textstellen eingefügt. Da Leerzeichen in der Regel nicht zur Auswahl gehören, werden die ausgewählten Bereiche ohne Leerzeichen aneinander gereiht eingefügt. Die „addRange()“-Methode läuft derzeit nur im Firefox. Andere Browser markieren lediglich den ersten definierten Bereich.

selection-api_range
Ausgewählte „<strong>“-Elemente

Mit der Methode „getRangeAt()“ ist es möglich, die Inhalte der einzelnen Auswahlbereiche anzusprechen. Die Eigenschaft „rangeCount“ gibt zudem Auskunft über die Anzahl der Bereiche im Dokument.

var ausgabe;

for (var i = 0; i < auswahl.rangeCount; i++) {
  if (i > 0) ausgabe += ", ";
  ausgabe += auswahl.getRangeAt(i);
}

alert(ausgabe);

Im Beispiel werden alle Bereiche einer Variablen hinzugefügt und per Komma voneinander getrennt. Anschließend erfolgt die Ausgabe aller ausgewählten Inhalte in einem Dialogfenster.

Die Methode „removeRange()“ ermöglicht es, einen bestimmten Bereich wieder zu löschen. Ihr wird der zu entfernende Bereich übergeben.

auswahl.removeRange(auswahl.getRangeAt(1));

Im Beispiel wird nur der zweite Bereich der Auswahl entfernt. Mit der Methode „removeAllRanges()“ würden hingegen alle Bereiche des Dokumentes entfernt.

Kindelemente auswählen

Mit der Methode „selectAllChildren()“ lassen sich alle Kindelemente eines Elementes auswählen.

window.getSelection().selectAllChildren(document.getElementsByTagName("body")[0]);

Im Beispiel werden alle Kindelemente des „<body>“-Elements ausgewählt, somit also alle Inhaltselemente des Dokuments.

selection-api_selectallchildren
Ausgewählte Kindelemente

Alternativ können natürlich auch einzelne Absätze ausgewählt werden.

window.getSelection().selectAllChildren(document.getElementsByTagName("p")[0]);

Auswahl entfernen und ausgewählte Inhalte löschen

Um eine Auswahl komplett zu entfernen, verwenden wir die Methode „collapse()“. Sie erwartet zwei Angaben, die dazu dienen, den Textcursor nach der Auswahlentfernung zu platzieren. So muss zunächst das Element angegeben werden, in welches der Cursor platziert werden soll. Zusätzlich wird angegeben, ob der Cursor am Anfang des Elements („0“) oder am Ende („1“) platziert werden soll.

document.addEventListener("click", function() {
  window.getSelection().collapse(document.getElementsByTagName("p")[0], 1);
}, false);

Im Beispiel wird die Auswahl entfernt und der Cursor am Ende des ersten „<p>“-Elementes platziert. Die Cursorplatzierung funktioniert natürlich auch hier nur bei Elementen, die bearbeitbar sind.

Statt nur die Auswahl zu löschen, ist es mit „deleteFromDocument()“ möglich, den ausgewählten Inhalt aus der DOM-Struktur des Dokumentes zu löschen.

document.addEventListener("click", function() {
  window.getSelection().deleteFromDocument();
}, false);

Die Methode „deleteFromDocument()“ läuft in allen gängigen Browsern, auch im Internet Explorer. Während Chrome und Internet Explorer das Löschen ganzer Elemente erlauben, ist es im Firefox nur möglich, Texte innerhalb eines Elementes zu löschen.

Browserunterstützung

Grundsätzlich unterstützen alle großen Browser die Selection-API – allerdings nicht im selben Umfang. Leider ist das Verhalten der einzelnen Browser, wie im Beispiel von „deleteFromDocument()“, teils recht unterschiedlich.

(dpe)

Denis Potschien

Denis Potschien ist seit 2005 freiberuflich als Kommunikationsdesigner tätig, seit Anfang 2010 im Kreativkonsulat in Iserlohn, einem Büro für Gestaltung und Kommunikation. Dort betreut er kleine und mittelständische Unternehmen ebenso wie kommunale Körperschaften und Organisationen aus Südwestfalen und dem Ruhrgebiet. Als Webdesigner und -entwickler gehören HTML5 und CSS3 zu seinen Kernthemen, weshalb er dazu 2013 ein Buch geschrieben hat. „Pure HTML5 und CSS3“ richtet sich an alle, die Vorkenntnisse haben, sich aber bisher mit HTML5 und CSS3 nicht oder nur am Rande beschäftigt haben.