Erstellen eines WYSIWYG-Editors mit dem contentEditable-Attribut
() translation by (you can also view the original English article)
WYSIWYG-Editoren sind sehr beliebt. Vielleicht haben Sie auch irgendwann einen verwendet. Es stehen viele Bibliotheken zur Verfügung, die Ihnen beim Einrichten Ihres eigenen Editors helfen. Obwohl sie schnell eingerichtet werden können, gibt es auch Nachteile bei der Verwendung dieser Bibliotheken. Zunächst sind sie aufgebläht. Die meisten von ihnen haben ausgefallene Funktionen, die Sie möglicherweise nicht verwenden. Darüber hinaus kann das Anpassen des Aussehens dieser Editoren Kopfschmerzen bereiten.
In diesem Tutorial werden wir unseren eigenen leichtgewichtigen WYSIWYG-Editor erstellen. Am Ende dieses Tutorials haben Sie einen Editor mit grundlegenden Formatierungsfunktionen, der nach Ihren Vorlieben formatiert ist.
Beginnen wir mit der Einführung von execCommand
. Wir werden diesen Befehl verwenden, um unseren Editor ausgiebig zu implementieren.
Document.execCommand()
execCommand
ist eine Methode des Dokumentobjekts. Sie ermöglicht uns, den Inhalt einer bearbeitbaren Region zu manipulieren. Wenn sie in Verbindung mit contentEditable
verwendet wird, kann sie uns helfen, einen Rich-Text-Editor zu erstellen. Es gibt viele Befehle, wie das Hinzufügen eines Links, das Fett- oder Kursiv-Setzen einer Auswahl und das Ändern der Schriftgröße oder -farbe. Diese Methode folgt der Syntax:
1 |
document.execCommand(CommandName, ShowDefaultUI, ValueArgument); |
CommandName
ist eine Zeichenfolge, die den Namen des auszuführenden Befehls angibt. ShowDefaultUI
ist ein boolscher Wert, um anzugeben, ob die unterstützende Schnittstelle angezeigt werden soll oder nicht. Diese Option ist nicht vollständig implementiert, und es ist am besten, sie auf false festzulegen. ValueArgument
ist eine Zeichenfolge, um Informationen wie Bild-URL oder foreColor
bereitzustellen. Dieses Argument wird auf null
gesetzt, wenn für einen Befehl kein Wert erforderlich ist.
Wir müssen verschiedene Versionen dieser Methode verwenden, um verschiedene Funktionen zu implementieren. In den nächsten Absätzen werde ich alle nacheinander behandeln.
Befehle ohne Wert-Argument
Befehle wie Fettsatz, rechtsbündig setzen, rückgängig machen und wiederholen benötigen kein ValueArgument
. In solchen Fällen verwenden wir die folgende Syntax:
1 |
document.execCommand(commandName, false, null); |
CommandName
ist einfach der Name des Befehls wie justifyCenter
, justifyRight
, bold
, etc.
Befehle mit einem Wert-Argument
Befehle wie insertImage
, createLink
und foreColor
benötigen ein drittes Argument, um richtig zu funktionieren. Für diese Befehle benötigen Sie die folgende Syntax:
1 |
document.execCommand(commandName, false, value); |
Bei insertImage
ist der Wert die URL des einzufügenden Bildes. Im Fall von foreColor
wäre es ein Farbwert wie #FF9966
oder ein Name wie blue
.
Befehle, die Block-Style-Tags hinzufügen
Das Hinzufügen von HTML-Block-Stil-Tags erfordert, dass Sie formatBlock
als commandName
und den Tag-Namen als valueArgument
verwenden. Die Syntax würde wie folgt aussehen:
1 |
document.execCommand('formatBlock', false, tagName); |
Diese Methode fügt ein HTML-Block-Stil-Tag um die Zeile hinzu, welche die aktuelle Auswahl enthält. Es ersetzt auch alle Tags, die bereits dort vorhanden sind. tagName
kann eines der Headline-Tags (h1
-h6
), p
oder blockquote
sein.
Ich habe hier die häufigsten Befehle besprochen. Sie können Mozilla besuchen, um eine Liste aller verfügbaren Befehle zu erhalten.
Erstellen einer Werkzeugleiste
Mit den Grundlagen aus dem Weg, ist es Zeit, die Symbolleiste zu erstellen. Ich werde Font Awesome-Icons für die Schaltflächen verwenden. Sie haben vielleicht bemerkt, dass abgesehen von ein paar Unterschieden, alle execCommand
s eine ähnliche Struktur haben. Wir können dies zu unserem Vorteil nutzen, indem wir das folgende Markup für Symbolleistenschaltflächen verwenden:
1 |
<a href="#" data-command='commandName'><i class='fa fa-icon'></i></a> |
Auf diese Weise können Benutzer, wenn sie auf eine Schaltfläche klicken, basierend auf dem Wert des data-command
-Attributs mitteilen, welche Version von execCommand
verwendet werden soll. Hier sind ein paar Schaltflächen als Referenz:
1 |
<a href="#" data-command='h2'>H2</a> |
2 |
<a href="#" data-command='undo'><i class='fa fa-undo'></i></a> |
3 |
<a href="#" data-command='createlink'><i class='fa fa-link'></i></a> |
4 |
<a href="#" data-command='justifyLeft'><i class='fa fa-align-left'></i></a> |
5 |
<a href="#" data-command='superscript'><i class='fa fa-superscript'></i></a> |
Der Attributwert für den data-command
für die erste Schaltfläche ist h2
. Nach der Überprüfung auf diesen Wert in JavaScript verwenden wir die formatBlock
-Version der execCommand
-Methode. In ähnlicher Weise suggeriert die Schaltfläche superscript
, dass wir die no-valueArgument
-Version von execCommand
verwenden müssen.
Das Erstellen von foreColor
- und backColor
-Schaltflächen ist eine andere Geschichte. Sie stellen zwei Probleme dar. Je nachdem, wie viele Farben wir Benutzern zur Auswahl zur Verfügung stellen, kann das Schreiben von so viel Code ermüdet und fehleranfällig sein. Um dieses Problem zu beheben, können wir den folgenden JavaScript-Code verwenden:
1 |
var colorPalette = ['000000', 'FF9966', '6699FF', '99FF66','CC0000', '00CC00', '0000CC', '333333', '0066FF', 'FFFFFF']; |
2 |
|
3 |
var forePalette = $('.fore-palette'); |
4 |
|
5 |
for (var i = 0; i < colorPalette.length; i++) { |
6 |
forePalette.append('<a href="#" data-command="forecolor" data-value="' + '#' + colorPalette[i] + '" style="background-color:' + '#' + colorPalette[i] + ';" class="palette-item"></a>'); |
7 |
}
|
Beachten Sie, dass ich auch ein data-value
-Attribut für jede Farbe einstelle. Dies wird später als valueArgument
in der execCommand
-Methode verwendet.
Das zweite Problem ist, dass wir nicht so viele Farben auf einmal zeigen können, weil dies viel Platz in Anspruch nehmen würde und zu einer schrecklichen Benutzererfahrung führen würde. Mit etwas CSS können wir sicherstellen, dass die Farbpalette nur angezeigt wird, wenn ein Benutzer über die entsprechenden Schaltflächen zeigt. Das Markup für diese Schaltflächen muss auch auf Folgendes geändert werden:
1 |
<div class="fore-wrapper"><i class='fa fa-font'></i> |
2 |
<div class="fore-palette"> |
3 |
</div>
|
4 |
</div>
|
Um die Paletten nur bei hover
der Maus anzuzeigen, benötigen wir das folgende CSS:
1 |
.fore-palette, |
2 |
.back-palette { |
3 |
display: none; |
4 |
}
|
5 |
|
6 |
.fore-wrapper:hover .fore-palette, |
7 |
.back-wrapper:hover .back-palette { |
8 |
display: block; |
9 |
float: left; |
10 |
position: absolute; |
11 |
}
|
Es gibt viele andere CSS-Regeln in der CodePen-Demo, um die Symbolleiste präzistischer zu machen, aber das ist alles, was für die Kernfunktionalität benötigt wird.
Hinzufügen von Funktionen zum Editor
Jetzt ist es an der Zeit, unseren Editor funktionsfähig zu machen. Der dafür erforderliche Code ist überraschend klein.
1 |
$('.toolbar a').click(function(e) { |
2 |
|
3 |
var command = $(this).data('command'); |
4 |
|
5 |
if (command == 'h1' || command == 'h2' || command == 'p') { |
6 |
document.execCommand('formatBlock', false, command); |
7 |
}
|
8 |
|
9 |
if (command == 'forecolor' || command == 'backcolor') { |
10 |
document.execCommand($(this).data('command'), false, $(this).data('value')); |
11 |
}
|
12 |
|
13 |
if (command == 'createlink' || command == 'insertimage') { |
14 |
url = prompt('Enter the link here: ','http:\/\/'); |
15 |
document.execCommand($(this).data('command'), false, url); |
16 |
}
|
17 |
|
18 |
else document.execCommand($(this).data('command'), false, null); |
19 |
|
20 |
});
|
Wir beginnen mit dem Anfügen eines Klickereignisses an alle Symbolleistenschaltflächen. Immer wenn auf eine Symbolleistenschaltfläche geklickt wird, speichern wir den Wert des data-command
-Attributs der entsprechenden Schaltfläche in der Variable command
. Dies wird später verwendet, um die entsprechende Version der execCommand
-Methode aufzurufen. Es hilft beim Schreiben von prägnantem Code und vermeidet Wiederholungen.
Beim Festlegen von foreColor
und backColor
verwende ich das Attribut data-value
als drittes Argument. createLink
und insertImage
haben keinen konstanten url
-Wert, daher verwenden wir eine Eingabeaufforderung, um die Werte vom Benutzer abzurufen. Sie können auch zusätzliche Prüfungen durchführen, um sicherzustellen, dass url
gültig ist. Wenn die command
-Variable keinen der Bedingungen der if
-Blöcke erfüllt, führen wir die erste Version von execCommand
aus.
So sieht unser WYSIWYG Editor aus.



Sie können auch die automatische Speicherfunktion mithilfe von localStorage
implementieren, die ich in meinem letzten Tutorial erläutert habe.
Browserübergreifende Unterschiede
Verschiedene Browser weisen geringfügige Implementierungsunterschiede auf. Denken Sie beispielsweise daran, dass Internet Explorer bei der Verwendung von formatBlock
nur die Überschriften-Tags h1 - h6
, address
und pre
unterstützt. Sie müssen auch die Tag-Trennzeichen einschließen, wenn Sie den commandName
wie <h3>
spezifizieren.
Nicht alle Befehle werden von jedem Browser unterstützt. Internet Explorer unterstützt keine Befehle wie insertHTML
und hiliteColor
. Ebenso wird insertBrOnReturn
nur von Firefox unterstützt. Weitere Informationen zu Browserinkonsistenzen finden Sie auf dieser GitHub-Seite.
Letzte Gedanken
Das Erstellen eines eigenen WYSIWYG-Editors kann eine großartige Lernerfahrung sein. In diesem Tutorial habe ich viele Befehle behandelt und einiges an CSS für grundlegendes Styling verwendet. Als Übung schlage ich vor, dass Sie versuchen, eine Symbolleistenschaltfläche zu implementieren, um die Schriftart, font
, einer Textauswahl festzulegen. Die Implementierung ähnelt der der foreColor
-Schaltfläche.
Ich hoffe, Sie liebten dieses Tutorial und lernten etwas Neues. Wenn Sie Ihren eigenen WYSIWYG-Editor von Grund auf neu erstellt haben, können Sie im Kommentarbereich einen Link dazu hinterlassen.