Brugernavn:




Kodeord: Husk
Forside Forum Artikler Downloads Søg
 

Lav din egen WYSIWYG


I denne artikel skal vi se på hvordan man laver en såkaldt WYSIWYG editor.
WYSIWYG står for What You See Is What You Get.
På dansk: "Hvad du ser er hvad du får".

Det går ud på at man kan lave et script der virker på samme måde som et almindeligt tekstbehandlingsprogram som f.eks Word eller OO-Writer.
Det kan f.eks være nyttigt til folk der ikke har forstand på HTML, eller hvis man bare ikke gider sidde og skrive kode hele tiden.

Men nok snak, lad os komme igang med lidt teori.

TEORI
Vores editor skal bygges op på den måde at vi skal lave et iframe som skal være "Editable" - dvs. at vi skal have mulighed for at manipulere med indholdet i iframet.
Dernæst skal vi lave en række Javascript funktioner til at udføre de manipulationer vi vil have dem til via. f.eks tryk på knapper.

Men lad os allerførst starte med en grundskabelon.

GRUNDSKABELON
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4.     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
  5.     <link rel="stylesheet" type="text/css" href="/style.css" media="screen"/>
  6.     <title>WYSIWYG Editor</title>
  7. <script type="text/JavaScript">

  8. </script>
  9. </head>
  10. <body>

  11. <iframe name="editor" id="editor"></iframe>
  12. </body>
  13. </html>

Der er ikke det store i den kode, det i skal lægge mærke til er at vi har indsat et iframe, som vi har givet id"et "editor",
det skal vi bruge nu når vi skal gøre det "editable".
Det gøres via Javascript ved at sætte "DesignMode" til "on" på iframet.

DESIGNMODE
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4.     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
  5.     <link rel="stylesheet" type="text/css" href="/style.css" media="screen"/>
  6.     <title>WYSIWYG Editor</title>
  7. <script type="text/JavaScript">
  8.     var editor;
  9.         function init()
  10.         {
  11.             editor = document.getElementById("editor");
  12.             editor.contentWindow.document.designMode = "On";
  13.         }
  14. </script>
  15. </head>
  16. <body onload="init();">

  17. <iframe name="editor" id="editor"></iframe>
  18. </body>
  19. </html>

Som i kan se så har jeg lavet en funktion som jeg har kaldt "init" - det er lige meget hvad du kalder den, men for ikke at forvirre dig selv så kald den det samme som jeg gør i artiklen her.
Jeg har også lavet en variabel som jeg har kaldt "editor" - den bliver sat til at indeholde vores "iframe" - det kan du se i den første linje i funktionen.
Dernæst har jeg sat "contentWindow.document.designMode" til "on" på vores iframe, det betyder at vi nu kan skrive i iframet.
Det kan du afprøve ved at klikke i iframet, så det bliver sat i fokus, nu kan du skrive på tastaturet.

FORMATERING AF TEKST
Nu skal vi igang med at lave nogle knapper til at formatere den tekst vi skriver i iframet.
Til det er der allerede en indbygget funktion i javascript som vi kan bruge til det formål - den funktion hedder "execCommand",
execCommand skal have 3 forskellige parametre: "Command" - "T/F" - "Value".
Et eksempel er:
  • execCommand("FontSize", false, 2);

Som vil sætte skriftstørrelsen til 2.
Den funktion skal vi nu udføre ved tryk på en knap - så vi laver en yderligere funktion med execCommand i indholdet som vi kalder ved tryk på en knap:
  1. function txtCommand(command, value)
  2. {
  3.     editor.contentWindow.document.execCommand(command, false, value);
  4. }

Som i kan se har jeg lavet en funktion der hedder "txtCommand" som jeg har givet 2 parametre "command" og "value",
"command" er den type vi vil have execCommand til at udføre, f.eks "FontSize" eller "FontName",
"value" er den værdi som vores "command" skal have, det kunne f.eks være "2" hvis vi vil have "FontSize" til at være 2.

Nu skal vi bare have lavet en knap som udfører den funktion, vi starter med at lave en knap som laver teksten fed (bold).
  • <button onclick="txtCommand("Bold", "");"><b>B</b></button>

Nu tænker du nok "Du har ikke givet den nogen værdi" - og det er rigtigt nok, men det er fordi at "Bold, Italic & Underline" kun har een værdi, derfor undlader jeg det.
Hvis du indsætter den kode umiddelbart før iframet, skriver noget i iframet, markerer din tekst og trykker på knappen - så kan du se at teksten bliver fed, trykker du på knappen igen forsvinder "fed".

Nu viser jeg lige hele koden som den ser ud nu - jeg har tilføjet "Italic" og "Underline".
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4.     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
  5.     <link rel="stylesheet" type="text/css" href="style.css" media="screen"/>
  6.     <link rel="stylesheet" type="text/css" href="/style.css" media="screen"/>
  7.     <title>WYSIWYG Editor</title>
  8. <script type="text/JavaScript">
  9.     var editor;
  10.         function init()
  11.         {
  12.             editor = document.getElementById("editor");
  13.             editor.contentWindow.document.designMode = "On";
  14.         }
  15.         function txtCommand(command, value)
  16.         {
  17.             editor.contentWindow.document.execCommand(command, false, value);
  18.         }
  19. </script>
  20. </head>
  21. <body onload="init();">
  22. <button onclick="txtCommand("Bold", "");"><b>B</b></button>
  23. <button onclick="txtCommand("Italic", "");"><i>I</i></button>
  24. <button onclick="txtCommand("Underline", "");"><u>U</u></button><br />
  25. <iframe name="editor" id="editor"></iframe>
  26. </body>
  27. </html>

Allerede nu har vi en lille editor som vi rent faktisk kan bruge til noget, så nu skal vi igang med at udvide den - nu skal vi gøre så vi kan skifte skriftstørrelse,
til det skal vi bruge kommandoen "FontSize" som jeg fortalte om tidligere men denne gang skal vi ikke bruge knapper, men en "DropDown" (<select>).
  1.     <select onchange="txtCommand("FontSize", this.options[this.selectedIndex].value);">
  2.         <option value="1">10</option>
  3.         <option value="2">12</option>
  4.         <option value="3">14</option>
  5.         <option value="4">18</option>
  6.         <option value="5">24</option>
  7.         <option value="6">32</option>
  8.         <option value="7">48</option>
  9.     </select>

Som i kan se har jeg lavet en <select> menu hvor jeg har sat en eventHandler kaldet "onchange" på - dvs. sige at når <select>"en "changes" udføres txtCommand() med parametrene "FontSize" som "command", og "this.options[this.selectedIndex].value" som "value".
"this.options[this.selectedIndex].value" indeholder "value" på den <option> vi har valgt i vores select.

Nu har vi kigget lidt på hvordan man manipulerer med teksten, nu kan du selv eksperimentere lidt med hvilke funktioner du synes din editor bør indholde, jeg lægger et link i bunden af artiklen med en oversigt over de forskellige kommandoer du kan bruge.

VIS / SKJUL KILDE
Alle de kendte editorer har også en "vis kilde" knap, så man kan redigere direkte i koden hvis der er noget som driller.
"Hvordan kommer det til at foregå" spørger du måske dig selv om nu - og derfor tager vi lidt teori om hvordan vi laver det.

Vi skal have lavet et <textarea> som er identisk med vores "editor" rent udseendemæssigt, derfor skal vi nu bruge den "style.css" som jeg har inkluderet hele tiden.
Så vi skal lave en knap som kan "Vise / Skjule" kildekoden.

Men allerførst laver vi lige vores CSS dokument:
  1. #editor {border: 1px solid #000; width: 500px; height: 300px; }
  2. #code {border: 1px solid #000; width: 500px; height: 300px; display: none; }

Som i kan se er det ganske almindelig simpel CSS, men læg mærke til at vi har sat "display: none;" på "#code" som vi vil kalde vores <textarea>.
Så nu kan vi roligt gå igang med de ting vi skal bruge, vi starter med at sætte et <textarea> ind lige efter vores iframe.
  • <textarea id="code"></textarea>

Nu har vi vores tekstarea, så skal vi bare lave et par knapper og et par funktion, det lyder meget nemt - og det er det også hvis man har lidt "flair" for javascript og lidt logisk sans.
1:Vi skal laven funktion som gør følgende: "Overfører indholdet fra iframet til textareaet" - "Gør iframet usynligt og textareaet synligt".
2: Vi skal lave en funktion som gør det modsatte af den foregående.
3: Vi skal lave 2 knapper til at kalde hver af de to funktioner

Nummer 1
Vi laver en funktion som vi kalder "CodeMode" som skal vise os kildekoden, jeg viser lige hvordan den ser ud og forklarer den bagefter:
  1.         function CodeMode()
  2.         {
  3.             document.getElementById("code").value = editor.contentWindow.document.body.innerHTML;
  4.             document.getElementById("editor").style.display = "none";
  5.             document.getElementById("code").style.display = "inline";
  6.         }

Linje 1: Vi giver textareae"s "value" indeholder af iframets "innerHTML".
Linje 2: Vi gør iframet "usynligt" ved at sætte "display: none;" på det.
Linje 3: Vi gør textareaet synligt ved at sætte "display: inline;" på det.

Og vores kode til at komme tilbage fra kildekoden ser sådan her ud - den kalder vi "NormalMode":
  1.         function NormalMode()
  2.         {
  3.             editor.contentWindow.document.body.innerHTML = document.getElementById("code").value;
  4.             document.getElementById("editor").style.display = "inline";
  5.             document.getElementById("code").style.display = "none";
  6.         }
Den vil jeg ikke forklare mere om, den gør bare det samme som "CodeMode" funktionen.

Så er der ikke mere tilbage en at sætte et par knapper ind som kan udføre de 2 funktioner - her har i hele koden samlet.
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4.     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
  5.     <link rel="stylesheet" type="text/css" href="style.css" media="screen"/>
  6.     <title>WYSIWYG Editor</title>
  7. <script type="text/JavaScript">
  8.     var editor;
  9.         function init()
  10.         {
  11.             editor = document.getElementById("editor");
  12.             editor.contentWindow.document.designMode = "On";
  13.         }
  14.         function txtCommand(command, value)
  15.         {
  16.             editor.contentWindow.document.execCommand(command, false, value);
  17.         }
  18.         function NormalMode()
  19.         {
  20.             editor.contentWindow.document.body.innerHTML = document.getElementById("code").value;
  21.             document.getElementById("editor").style.display = "inline";
  22.             document.getElementById("code").style.display = "none";
  23.         }
  24.         function CodeMode()
  25.         {
  26.             document.getElementById("code").value = editor.contentWindow.document.body.innerHTML;
  27.             document.getElementById("editor").style.display = "none";
  28.             document.getElementById("code").style.display = "inline";
  29.         }
  30. </script>
  31. </head>
  32. <body onload="init();">
  33.     <select onchange="txtCommand("FontSize", this.options[this.selectedIndex].value);">
  34.         <option value="1">10</option>
  35.         <option value="2">12</option>
  36.         <option value="3">14</option>
  37.         <option value="4">18</option>
  38.         <option value="5">24</option>
  39.         <option value="6">32</option>
  40.         <option value="7">48</option>
  41.     </select>
  42. <button onclick="txtCommand("Bold", "");"><b>B</b></button>
  43. <button onclick="txtCommand("Italic", "");"><i>I</i></button>
  44. <button onclick="txtCommand("Underline", "");"><u>U</u></button><br />
  45. <iframe name="editor" id="editor"></iframe>
  46. <textarea id="code"></textarea>
  47. <br />
  48. <input type="button" value="Kildekode" onclick="CodeMode();" />
  49. <input type="button" value="Design" onclick="NormalMode();" />
  50. </body>
  51. </html>

AFSLUTNING
Nu har du faktisk en ganske simpel WYSIWYG editor som der bare venter på at du fylder nogle flere funktioner på den.
Det kunne f.eks være mulighed for at Centere, Højrejustering, Lister, SuperScript osv osv.

Og så kan du selvfølgelig også gøre en masse ud af designet, så du til sidst får en rigtig lækker editor.

Jeg vil lige påpege at det måske ikke er superkode jeg har valgt at skrive, men det er pga. at alle skal kunne være med og forstå koden, kan man oop osv kan man altid selv omskrive det.

Editoren er testet og virker i Internet Eksplorer og Mozilla FireFox

Her til sidst er nogle links som jeg lovede i løbet af artiklen:
LINKS
Oversigt over kommandoer: http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/commandids.asp
FCK-Editor: http://www.fckeditor.net/
Sidst redigeret 21:36 - 21/01/2007
Oprettet af:

Javascript

Point modtaget: 0

Rating: 4.6
20:54 21/01/2007

Kommentarer

Giv din mening tilkende om denne artikel, eller læs andres.
Har du spørgsmål eller brug for hjælp til denne artikel henvises du til forummet.
Nice ;) 5/5
Oprettet af:
  Mail
11:24 22/01/2007
HVOR SYGT MAN!

Har lige gået og kigget efter en artikel til sådan en editor :O
Oprettet af:
  Mail
12:09 22/01/2007
Suverent :D Javascript er et genialt sprog, hvis man nu havde lidt evner med Ajax kunne det blive rigtig fedt ;)
Sidst redigeret 16:54 - 29/01/2007
Oprettet af:
  Mail
14:02 22/01/2007
Fedt nok!
God artikel! 5/5
Oprettet af:
  Mail
14:26 22/01/2007
Nice!! :D
Oprettet af:
  Mail
15:35 22/01/2007
Rigtig fedt 5/5
Oprettet af:
  Mail
20:26 22/01/2007
Fandeme en god artikel!
Oprettet af:
  Mail
07:44 24/01/2007
10 tal herfra. :)
Oprettet af:
  Mail
01:52 26/01/2007
Kan man kun lave sådan en editor i Javascript?
Oprettet af:
  Mail
12:56 11/02/2007
Hvad tænker du på Nikolaj?
Altså Word f.eks er jo efter samme koncept, det er bare skrevet i C (Går jeg ud fra) og ikke javascript.

Men hvis du mener om man kan lave sådan en f.eks i PHP - så ja det kan man i teorien godt - men det vil godt nok være at voldtage sin server, da man skal have gang i en ordentligt suppe af RegExp og en masse andet grej - så det kan jeg overhovedet ikke anbefale du går igang med :)
Oprettet af:
  Mail
05:46 15/02/2007
Du skal være oprettet og logget ind for at kommentere en artikel
Copyright © Rowl.dk v/ Michael Raagaard | 2005-10 | Alle rettigheder forbeholdes