Erstellen von Aktionen für ausgewählten Text mit der Selection API

Avatar of Preethi
Preethi am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Klicken, ziehen, loslassen: Sie haben gerade Text auf einer Webseite ausgewählt – wahrscheinlich, um ihn zu kopieren und woanders einzufügen oder zu teilen. Wäre es nicht cool, wenn das Auswählen dieses Textes Optionen anzeigen würde, die diese Aufgaben erleichtern? Das leistet ein Auswahlmenü.

Auswahlmenüs sind Ihnen vielleicht schon bekannt, wenn Sie jemals einen Online-Editor verwendet haben. Wenn Sie Text auswählen, können Formatierungsoptionen über ihm schweben. Tatsächlich schreibe ich diesen Entwurf in einem Editor, der genau das tut.

Lassen Sie uns sehen, wie wir ein solches Auswahlmenü mit der Selection API von JavaScript erstellen können. Die API gibt uns Zugriff auf den Bereich und Inhalt des ausgewählten Bereichs auf einer Webseite. So können wir das Auswahlmenü **genau über** dem ausgewählten Text platzieren und auf den ausgewählten Text selbst zugreifen.

Hier ist ein HTML-Snippet mit Beispieltext

<article>
  <h1>Select over the text below</h1> 
  <p>Cascading Style Sheets (CSS) is a style sheet language used for describing the presentation of a document written in a markup language such as HTML. CSS is a cornerstone technology of the World Wide Web, alongside HTML and JavaScript. CSS is designed to enable the separation of presentation and content, including layout, colors, and fonts. This separation can improve content accessibility, provide more flexibility and control in the specification of presentation characteristics. </p>
</article>
<template><span id="control"></span></template>

Ganz am Ende gibt es ein <template>-Tag. Der <span> darin ist unser Steuerelement für das Auswahlmenü. Alles innerhalb eines <template>-Tags wird auf der Seite **nicht gerendert**, bis es später mit JavaScript zur Seite hinzugefügt wird. Wir fügen das Steuerelement für das Auswahlmenü hinzu, wenn der Benutzer Text auswählt. Und wenn der Benutzer diesen Text auswählt, fordert unser Auswahlmenü den Benutzer auf, ihn zu twittern.

Hier ist der CSS-Code zur Gestaltung

#control {
    background-image: url("data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 width='40px' height='40px'><foreignObject width='40px' height='40px'><div xmlns='http://www.w3.org/1999/xhtml' style='width:40px;height:40px;line-height:40px;text-align:center;color:transparent;text-shadow: 0 0 yellow, 2px 4px black, -1px -1px black;font-size:35px;'>💬</div></foreignObject></svg>");
  cursor: pointer;
  position: absolute;
  width: 40px;
  height: 40px;
}
#control::before{
  background-color: black;
  color: white;
  content: " tweet this! ";
  display: block;
  font-weight: bold;
  margin-left: 37px;
  margin-top: 6px;
  padding: 2px;
  width: max-content;
  height: 20px;
}

Schauen Sie sich diesen Artikel an, um zu erfahren, wie ich ein Emoji (💬) für das Hintergrundbild verwendet habe.

Bisher ist der Beispieltext vorbereitet und das Steuerelement für das Auswahlmenü wurde gestaltet. Kommen wir nun zu JavaScript. Wenn eine Auswahl getroffen wird, erhalten wir die Größe und Position des ausgewählten Bereichs auf der Seite. Dann verwenden wir diese Messungen, um die Position des Steuerelements für das Auswahlmenü am oberen Mittelpunkt des ausgewählten Bereichs zuzuweisen.

var control = document.importNode(document.querySelector('template').content, true).childNodes[0];
document.querySelector('p').onpointerup = () => {
  let selection = document.getSelection(), text = selection.toString();
  if (text !== "") {
    let rect = selection.getRangeAt(0).getBoundingClientRect();
    control.style.top = `calc(${rect.top}px - 48px)`;
    control.style.left = `calc(${rect.left}px + calc(${rect.width}px / 2) - 40px)`;
    control['text']= text; 
    document.body.appendChild(control);
  }
}

In diesem Code erhalten wir zuerst eine Kopie des Steuerelements für das Auswahlmenü innerhalb von <template> und weisen es dann der Variablen control zu.

Als Nächstes schreiben wir die Handler-Funktion für das onpointerup-Ereignis des Elements, das den Beispieltext enthält. Innerhalb der Funktion erhalten wir die Auswahl und die ausgewählte Zeichenkette mit document.getSelection(). Wenn die ausgewählte Zeichenkette **nicht** leer ist, ermitteln wir die Größe und Position des ausgewählten Bereichs mit getBoundingClientRect() und speichern sie in der Variablen rect.

Mithilfe von rect berechnen und weisen wir die top- und left-Positionen von control zu. Auf diese Weise wird das Steuerelement für das Auswahlmenü etwas über dem ausgewählten Bereich und horizontal zentriert platziert. Wir weisen auch die ausgewählte Zeichenkette einer benutzerdefinierten Eigenschaft von control zu. Dies wird später zum Teilen des Textes verwendet.

Und schließlich fügen wir control mit appendChild() zur Webseite hinzu. An diesem Punkt, wenn wir einen Teil des Beispieltextes auf der Seite auswählen, erscheint das Steuerelement für das Auswahlmenü auf dem Bildschirm.

Jetzt kommt der Code, der ausgeführt wird, wenn auf das Steuerelement für das Auswahlmenü geklickt wird. Mit anderen Worten, wir sorgen dafür, dass der Text getwittert wird, wenn auf die Aufforderung geklickt wird.

control.addEventListener('pointerdown', oncontroldown, true);

function oncontroldown(event) {
  window.open(`https://twitter.com/intent/tweet?text=${this.text}`)
  this.remove();
  document.getSelection().removeAllRanges();
  event.stopPropagation();
}

Wenn auf das Steuerelement geklickt wird, öffnet sich ein Tab mit der "Neuer Tweet"-Seite von Twitter, inklusive des ausgewählten Texts, der zum Versenden bereit ist.

Nach der Tweet-Aufforderung wird das Steuerelement für das Auswahlmenü nicht mehr benötigt und entfernt, zusammen mit jeder auf der Seite getroffenen Auswahl. Die Art und Weise, wie das pointerdown-Ereignis weiter im DOM-Baum nach unten weitergegeben wird, wird an dieser Stelle ebenfalls gestoppt.

Wir benötigen auch einen Event-Handler für das onpointerdown-Ereignis der Seite.

document.onpointerdown = ()=> {    
  let control = document.querySelector('#control');
  if (control !== null) {control.remove();document.getSelection().removeAllRanges();}
}

Jetzt werden das Steuerelement und jede auf der Seite getroffene Auswahl entfernt, wenn irgendwo auf der Seite geklickt wird, außer auf das Steuerelement für das Auswahlmenü.

Demo

Hier ist eine verschönerte Version, die Chris zusammengestellt hat.

Und hier ist ein Beispiel, das mehr als ein Steuerelement im Auswahlmenü zeigt.

Über das <template>

Es ist nicht unbedingt notwendig, es zu verwenden. Stattdessen können Sie auch versuchen, das Steuerelement auf andere Weise zu verstecken und anzuzeigen, z. B. mit dem HTML-Attribut hidden oder der CSS-Eigenschaft display. Sie können ein Steuerelement für ein Auswahlmenü auch direkt in JavaScript erstellen. Die Wahl der Kodierung hängt davon ab, wie effizient Sie sie umsetzen und welche Fallbacks Sie gegebenenfalls verwenden, sowie davon, wie sie in Ihre Anwendung passen.

Einige UI/UX-Hinweise

Auch wenn dies ein schöner Effekt ist, gibt es einige Dinge zu beachten, um ein gutes Benutzererlebnis zu gewährleisten. Vermeiden Sie es beispielsweise, Ihren eigenen Text in die Textauswahl einzufügen – z. B. einen Link zurück zu Ihrer Website im automatisch generierten Tweet anzuhängen. Das ist aufdringlich und nervig. Wenn es einen Grund dafür gibt, wie z. B. das Hinzufügen einer Quellenangabe, lassen Sie den Benutzer eine Vorschau des endgültigen Textes sehen, bevor er ihn postet. Andernfalls kann der Benutzer durch die Ergänzung verwirrt oder überrascht sein.

Noch etwas: Es ist am besten, wenn das Menü-Steuerelement nicht im Weg ist. Wir wollen nicht, dass es zu viel vom umgebenden Inhalt verdeckt. Eine solche Sache summiert sich zu CSS-„Datenverlust“ und das wollen wir vermeiden.

Fazit: Verstehen Sie, warum Benutzer Text auf Ihrer Website auswählen müssen, und fügen Sie die Steuerelemente so hinzu, dass sie nicht von dem ablenken, was sie tun möchten.