Maak een WYSIWYG-editor met het kenmerk contentEditable

WYSIWYG-editors zijn behoorlijk populair. Misschien heb je er op een gegeven moment ook een gebruikt. Er zijn veel bibliotheken beschikbaar om u te helpen bij het instellen van uw eigen editor. Hoewel ze snel kunnen worden ingesteld, zijn er ook nadelen aan het gebruik van deze bibliotheken. Om te beginnen zijn ze opgeblazen. De meesten van hen hebben mooie functies die je misschien niet gebruikt. Bovendien kan het lastig zijn om het uiterlijk van die editors aan te passen.

In deze tutorial zullen we onze eigen lichtgewicht WYSIWYG-editor bouwen. Aan het einde van deze zelfstudie hebt u een editor met basisformatteringsmogelijkheden die is afgestemd op uw voorkeuren.

Laten we beginnen met de introductie van execCommand. We zullen dit commando gebruiken om onze editor uitgebreid te implementeren.

Document.execCommand ()

execCommand is een methode van het document-object. Hiermee kunnen we de inhoud van een bewerkbaar gebied manipuleren. Bij gebruik naast contentEditable, het kan ons helpen een rich-text-editor te maken. Er zijn veel commando's beschikbaar zoals het toevoegen van een link, het maken van een selectie stoutmoedig of cursief, en het veranderen van lettergrootte of kleur. Deze methode volgt de syntaxis:

document.execCommand (CommandName, ShowDefaultUI, ValueArgument);

commandonaam is een tekenreeks die de naam van de uit te voeren opdracht aangeeft. ShowDefaultUIis een Booleaanse waarde om aan te geven of de ondersteunende interface moet worden weergegeven of niet. Deze optie is niet volledig geïmplementeerd en het is het beste om deze in te stellen op false. ValueArgument is een reeks om informatie zoals afbeeldings-URL of voorgrond-kleur. Dit argument is ingesteld op nul wanneer een opdracht geen waarde vereist om in werking te treden.

We zullen verschillende versies van deze methode moeten gebruiken om verschillende functies te implementeren. In de volgende paragrafen zal ik ze allemaal een voor een bespreken.

Opdrachten zonder waardeargument

Commando's zoals vet, rechtvaardigen, ongedaan maken en opnieuw uitvoeren hebben geen a nodig ValueArgument. In dergelijke gevallen gebruiken we de volgende syntaxis:

document.execCommand (commandName, false, null);

commandonaam is gewoon de naam van commando zoals justifyCenterjustifyRightstoutmoedig, enz. 

Opdrachten met een waardeargument

Commando's zoals Voeg afbeelding in, CreateLink en voorgrond-kleur heb een derde argument nodig om goed te kunnen werken. Voor deze opdrachten hebt u de volgende syntaxis nodig:

document.execCommand (commandName, false, value);

Voor Voeg afbeelding in, de waarde zou de URL zijn van de afbeelding die moet worden ingevoegd. In het geval van voorgrond-kleur, het zou een kleurwaarde zoals zijn # FF9966 of een naam als blauw

Opdrachten die blokstijlmarkeringen toevoegen

Het toevoegen van HTML-blokstijlen vereist dat je gebruikt formatBlock zoals commandonaam en de tagnaam als valueArgument. De syntaxis zou vergelijkbaar zijn met:

document.execCommand ('formatBlock', false, tagName);

Met deze methode wordt een tag met een HTML-blokstijl rond de regel toegevoegd die de huidige selectie bevat. Het vervangt ook elke tag die daar al bestond. tagName kan een van de koptags zijn (h1-h6), p of blockquote

Ik heb de meest voorkomende commando's hier besproken. U kunt Mozilla bezoeken voor een lijst met alle beschikbare opdrachten.

Een werkbalk maken

Met de basis uit onze weg, is het tijd om de werkbalk te maken. Ik zal Font Awesome-pictogrammen gebruiken voor de knoppen. Het is je misschien opgevallen dat er een paar verschillen buiten beschouwing worden gelaten, alle execCommands hebben een vergelijkbare structuur. We kunnen dit in ons voordeel gebruiken door de volgende markup voor werkbalkknoppen te gebruiken:

Op deze manier kunnen gebruikers die op een knop klikken, zien welke versie van execCommand te gebruiken op basis van de waarde van data-commando attribuut. Hier zijn enkele knoppen ter referentie:

H2    

De data-commando kenmerkwaarde voor de eerste knop is h2. Na het controleren van deze waarde in JavaScript, zullen we de formatBlock versie van de execCommand methode. Op dezelfde manier, voor de laatste knop, superscript suggereert dat we het nee moeten gebruiken valueArgument versie van execCommand.

Creëren voorgrond-kleur en BackColor knoppen is een ander verhaal. Ze vormen twee problemen. Afhankelijk van het aantal kleuren waaruit gebruikers kunnen kiezen, kan het schrijven van die code vermoeiend en foutgevoelig zijn. Om dit probleem aan te pakken, kunnen we de volgende JavaScript-code gebruiken:

var colorPalette = ['000000', 'FF9966', '6699FF', '99FF66', 'CC0000', '00CC00', '0000CC', '333333', '0066FF', 'FFFFFF']; var forePalette = $ ('. voorgrond palet'); for (var i = 0; i < colorPalette.length; i++)  forePalette.append(''); 

Merk op dat ik ook een begin data-value kenmerk voor elke kleur. Dit wordt later gebruikt als valueArgument in de execCommand methode.

Het tweede probleem is dat we niet altijd zoveel kleuren kunnen weergeven, omdat dit veel ruimte in beslag zou nemen en zou resulteren in een vreselijke gebruikerservaring. Met behulp van een beetje CSS kunnen we ervoor zorgen dat het kleurenpalet alleen verschijnt als een gebruiker boven de respectieve knoppen zweeft. De markup voor deze knoppen moet ook worden gewijzigd in het volgende:

Om de paletten alleen weer te geven zweven, we hebben de volgende CSS nodig:

.voorpalet, .back-palet display: none;  .vooroverpakking: hover .voorpalet, .back-wrapper: hover .back-palette display: block; zweven: links; positie: absoluut; 

Er zijn veel andere CSS-regels in de CodePen-demo om de werkbalk mooier te maken, maar dat is alles wat nodig is voor de kernfunctionaliteit.

Functionaliteit aan de editor toevoegen

Nu is het tijd om onze editor functioneel te maken. De code die daarvoor nodig is, is verrassend klein.

$ ('. werkbalk a'). klik (functie (e) var command = $ (this) .data ('command'); if (command == 'h1' || command == 'h2' || command == 'p') document.execCommand ('formatBlock', false, command); if (command == 'forecolor' || command == 'backcolor') document.execCommand ($ (this) .data ( 'opdracht'), false, $ (this) .data ('value')); if (opdracht == 'createlink' || command == 'insertimage') url = prompt ('Voer hier de link in:' , 'http: \ / \ /'); document.execCommand ($ (this) .data ('command'), false, url); else document.execCommand ($ (this) .data ('command'), false, null););

We beginnen met het toevoegen van een klikgebeurtenis aan alle werkbalkknoppen. Wanneer op een werkbalkknop wordt geklikt, slaan we de waarde van de data-commando kenmerk van de respectieve knop in de variabele, commando. Dit wordt later gebruikt om de juiste versie van de execCommand methode. Het helpt bij het schrijven van beknopte code en voorkomt herhaling.

Bij het instellen voorgrond-kleur en BackColor, Ik gebruik de data-value attribuut als het derde argument. CreateLink en Voeg afbeelding in heb geen constante url waarde, dus gebruiken we een prompt om de waarden van de gebruiker te krijgen. U wilt misschien ook extra controles uitvoeren om ervoor te zorgen dat het url is geldig. Als het commando variabele voldoet niet aan een van de als blokken, we hebben de eerste versie van execCommand

Dit is wat onze WYSIWYG-editor eruitziet.

U kunt de functie voor automatisch opslaan ook gebruiken met lokale opslag die ik heb besproken in mijn laatste zelfstudie.

Cross-Browser verschillen

Verschillende browsers hebben kleine implementatieverschillen. Houd er bijvoorbeeld rekening mee dat bij gebruik formatBlock, Internet Explorer ondersteunt alleen koerslabels h1 - h6, adres en pre. U moet ook de scheidingstekens voor tags toevoegen bij het opgeven van de commandonaam net zoals

.

Niet alle opdrachten worden door elke browser ondersteund. Internet Explorer biedt geen ondersteuning voor opdrachten zoals insertHTML en hiliteColor. evenzo, insertBrOnReturn wordt alleen door Firefox ondersteund. Je kunt meer lezen over inconsistenties van browsers op deze GitHub-pagina.

Laatste gedachten

Het maken van uw eigen WYSIWYG-editor kan een geweldige leerervaring zijn. In deze tutorial heb ik veel commando's behandeld en een aantal CSS gebruikt voor basisstyling. Als een oefening, zou ik voorstellen dat u een knop op de werkbalk probeert te implementeren om de doopvont van een tekstselectie. De implementatie zal vergelijkbaar zijn met die van de voorgrond-kleur knop. 

Ik hoop dat je deze tutorial leuk vond en iets nieuws hebt geleerd. Als je vanuit het niets je eigen WYSIWYG-editor hebt gemaakt, kun je hiernaar verwijzen in het gedeelte Opmerkingen.