Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Un editor di testi per il Web in JavaScript

Guida alla creazione di un editor HTML in JavaScript da utilizzare nel proprio Browser
Guida alla creazione di un editor HTML in JavaScript da utilizzare nel proprio Browser
Link copiato negli appunti

In questo articolo vedremo come inserire nel proprio sito un piccolo editor in grado di formattare il testo con delle barre degli strumenti - stile Word Processor - e ricavare del codice HTML.

Può essere utile sia come vero e proprio generatore di HTML, sia come campo di testo per scrivere e-mail, sia può essere utilizzato all'interno di sistemi di Content Management per favorire la formattazione del testo ad utenti inesperti.

Il codice è basato sulla proprietà designMode, che trasforma i documenti HTML in editor di testo. Questa proprietà, in passato supportata soltanto da Microsoft Internet Explorer, è ora finalmente implementata anche da Mozilla 1.3.

Realizzazione del modulo HTML

Presentiamo il codice HTML per la realizzazione della prima barra degli strumenti, quella su cui bisogna agire per modificare il testo. La barra è raffigurata nell'immagine qui sotto:

Cinque selectbox con le opzioni per il testo

  <select ID="ParagraphStyle"
onchange="formatC('formatBlock',this[this.selectedIndex].value);this.selectedIndex=0">
    <option selected>Paragrafo
    <option value="<H1>">Titolo 1 <H1>
    <option value="<H2>">Titolo 2 <H2>
    <option value="<H3>">Titolo 3 <H3>
    <option value="<H4>">Titolo 4 <H4>
    <option value="<H5>">Titolo 5 <H5>
    <option value="<H6>">Titolo 6 <H6>
    <option value="<PRE>">Formattato <PRE>
  </select>
  <select ID="FontName" onchange="formatC('fontnamÈ,this[this.selectedIndex].value);this.selectedIndex=0">
    <option class="heading" selected>Tipo Carattere
    <option value="Arial">Arial
    <option value="Arial Black">Arial Black
    <option value="Arial Narrow">Arial Narrow
    <option value="Comic Sans MS">Comic Sans MS
    <option value="Courier New">Courier New
    <option value="System">System
    <option value="Times New Roman">Times New Roman
    <option value="Verdana">Verdana
    <option value="Wingdings">Wingdings
  </select>
  <select ID="FontSize" onchange="formatC('fontsizÈ,this[this.selectedIndex].value);this.selectedIndex=0">
    <option class="heading" selected>Dimensione
    <option value="1">1
    <option value="2">2
    <option value="3">3
    <option value="4">4
    <option value="5">5
    <option value="6">6
    <option value="7">7
  </select>
  <select ID="FontColor" onchange="formatC('forecolor',this[this.selectedIndex].value);this.selectedIndex=0">
    <option class="heading" selected>Colore Testo
    <option value="red">rosso
    <option value="blue">blu
    <option value="green">verde
    <option value="black">nero
  </select>
  <select ID="FontBackColor" onchange="formatC('backcolor',this[this.selectedIndex].value);this.selectedIndex=0">
    <option class="heading" selected>Colore Sfondo
    <option value="red">rosso
    <option value="blue">blu
    <option value="green">verde
    <option value="black">nero
    <option value="yellow">giallo
    <option value="">bianco
  </select>
</div>

Il codice è formato da cinque selectbox che impostano, nell'ordine, il tipo di paragrafo, il tipo di carattere, la dimensione del font, il colore del testo e il colore dello sfondo.

La prima opzione delle selectbox è sempre costituita dalla spiegazione della sua funzione. Andando a selezionare un valore (evento onChange) verrà eseguita la funzione javascript formatC - che vedremo in dettaglio più avanti - seguita dall'automatico ritorno alla prima opzione (indice 0).

La parola chiave this restituisce l'oggetto stesso (in questo caso la selectbox), quindi this.selectedIndex indica l'indice dell'opzione selezionata nella selectbox.

Vediamo ora la seconda barra degli strumenti, raffigurata anch'essa dalla seguente immagine:

Tredici pulsanti per formatare il testo

A questo punto troviamo il campo dove inserire il testo. Possiamo notare che in realtà non è una textarea, come si sarebbe potuto supporre, ma un iframe:

Un iframe è una parte di una pagina Web che può essere trattata come documento a sé stante. Vediamo come renderlo editabile con javascript.

Inizializzazione dell'iframe contenente il testo

Per prima cosa abbiamo bisogno di settare le variabili globali, cioè quelle variabili che agiscono sull'intera pagina:


var str_iFrameDoc = (document.all)?
"document.frames("Composition").document;":
"document.getElementById("Composition").contentDocument;";

Creiamo la variabile booleana bHtmlMode per indicare se ci troviamo in modalità di visualizzazione del codice HTML. Per default la impostiamo su false.

La variabile str_iFrameDoc ci serve, invece, per realizzare la compatibilità tra i browser. Infatti una grande differenza tra Mozilla e IE è la modalità di accesso all'oggetto document di un iframe.

Mozilla usa lo standard W3C:

document.getElementById("nome_frame").contentDocument
mentre Internet Explorer richiede:
document.frames("nome_frame").document

Quindi, a seconda del browser utilizzato dal client, memorizziamo nella stringa str_iFrameDoc il giusto codice.

Per far ciò utilizziamo l'operatore condizionale condition ? expr1 : expr2 . In pratica se l'espressione document.all restituisce il valore true sappiamo che il client sta utilizzando Internet Explorer ed utilizziamo la sua sintassi, altrimenti utilizziamo quella aderente allo standard W3C.

Analizziamo ora il seguente script:

onload = initialize;

function initialize() {
  iFrameDoc = eval(str_iFrameDoc);
 iFrameDoc.open();
  iFrameDoc.write("<HTML><BODY MONOSPACE STYLE='font:10pt arial,sans-serif'></BODY></HTML>");
  iFrameDoc.close();
  iFrameDoc.designMode = "On";
 Â
  document.getElementById("switchMode").checked = false;

  if (!document.all) {
  document.getElementById("taglia").style.visibility = "hidden";
  document.getElementById("copia").style.visibility = "hidden";
  document.getElementById("incolla").style.visibility = "hidden";
  }
}

La funzione initialize

Con la funzione eval

Apriamo quindi per la scrittura il nostro iframe e al suo interno scriviamo il tag body, dandogli uno stile monospazio per renderlo simile ad una textarea. Infine richiudiamo l'iframe.

La proprietà designMode

Impostiamo ora su false il valore della proprietà checked della chekbox relativa al cambio di modalità di visualizzazione. Ciò è necessario perché Mozilla non reimposta automaticamente questo campo al refresh della pagina. Possiamo notare che in questo caso anche IE accetta la sintassi del W3C.

Infine, se il browser utilizzato dal client non è IE, nascondiamo i div che contengono i tastini taglia, copia e incolla. Facciamo ciò perché questi comandi non sono supportati da Mozilla.

Formattazione del testo

A questo punto vediamo come formattare il testo. Abbiamo bisogno, prima di tutto, di creare un controllo per disabilitare gli strumenti della toolbar in caso di visualizzazione in modalità HTML.


 if (!bHtmlMode) return true;

 alert("Deselezionare "Visualizza HTML" per utilizzare le barre degli strumenti");
 setFocus();
 return false;
}

Ricordiamo che la variabile bHtmlMode indica se ci troviamo in modalità HTML. Quindi, nel caso questa sia impostata sul valore true, la funzione validateMode restituirà un messaggio di errore (vedremo in seguito come passare da una modalità all'altra), dopodiché chiamerà la funzione setFocus:

function setFocus() {
if (document.all)
 document.frames("Composition").focus();
else
 document.getElementById('Composition').contentWindow.focus()
return;
}

Questa funzione altro non fa che riportare il focus all'interno dell'iframe. Anche qui il problema è dato dall'incompatibilità tra i browser, come si può facilmente vedere. Osserviamo ora la funzione formatC:

function formatC(what,opt) {
 if (!validateMode())Â return;

 iFrameDoc = eval(str_iFrameDoc);
 iFrameDoc.execCommand(what,false,opt);

 setFocus();
}

Per prima cosa la funzione formatC

Il metodo execCommand

execCommand accetta tre parametri. Il primo, obbligatorio, specifica il comando da eseguire. Il secondo parametro è un booleano opzionale. Specifica se visualizzare un'interfaccia utente, se il comando la supporta. L'opzione di default è false. Il terzo parametro, opzionale, specifica il valore da assegnare al comando.

Se torniamo ad osservare la parte HTML dello script, possiamo notare che soltanto le funzioni contenute nelle selectbox passano questo valore alla funzione formatC, mentre le funzioni della terza barra degli strumenti passano solo la prima opzione, non avendo bisogno di un valore da assegnarli.

Visualizzazione dell'HTML

Vediamo ora la funzione che ci consente di passare dalla visualizzazione del testo formattato a quella dell'HTML.


 var testo;

 bHtmlMode = newMode;

 iFrameDoc = eval(str_iFrameDoc);
 riquadro = iFrameDoc.body;

 if (document.all) {
  if (bHtmlMode) {
   testo = riquadro.innerHTML;
   riquadro.innerText = testo;
  } else {
   testo = riquadro.innerText;
   riquadro.innerHTML = testo;
  }

 } else if(document.getElementById && document.createTextNode) {
  if (bHtmlMode) {
   testo = document.createTextNode(riquadro.innerHTML);
   riquadro.innerHTML = "";
   riquadro.appendChild(testo);
  } else {
   testo = document.createRange()
   testo.selectNodeContents(riquadro);
   riquadro.innerHTML = testo.toString();
  }Â Â
 }

 setFocus();
}

Abbiamo visto che selezionando o deselezionando la casella di controllo switchMode passiamo alla funzione setMode

A questo punto dobbiamo passare da una modalità di visualizzazione all'altra all'interno del riquadro editabile. Anche qui le maggiori difficoltà ci saranno date dalla compatibilità tra i browser. Per comodità utilizziamo il riferimento all'oggetto body del documento contenuto nell'iframe. Lo chiamiamo riquadro.

Analizziamo il codice dei due browser separatamente.

Nel caso di IE basta ricorrere a due semplici proprietà: innerHTML e innerText . Vediamo meglio di cosa si tratta.

  • innerHTML
  • innerText

Quindi mentre con innerHTML tutti i tag all'interno dell'oggetto saranno interpretati come codice, con innerText verranno visti semplicemente come testo.

In pratica se abbiamo selezionato la casella di controllo, e quindi vogliamo vedere il codice, impostiamo la proprietà innerText dell'oggetto body dell'iframe con il contenuto della proprietà innerHTML dello stesso, cioè prendiamo il codice HTML e lo reinseriamo nel riquadro sotto forma di testo.

Chiaramente quando deselezioniamo la casesella di controllo eseguiamo il procedimento contrario: prendiamo il testo e lo reinseriamo sotto forma di codice HTML.

Con Mozilla il codice è più complesso, perché la proprietà innerText non è più supportata e dobbiamo ricorrere a qualche altro espediente. Fortunatamente, però, il W3C ci offre un'ampia gamma di strumenti per accedere agli elementi della pagina.

In particolare, per passare dalla visualizzazione dell'HTML, ci basterà utilizzare i metodi createTextNode e appendChild.

Il metodo createTextNode permette di creare un nuovo nodo di testo. La stringa da inserire in tale nodo sarà, ovviamente, il codice contenuto nell'iframe. Per ricavarcelo possiamo continuare ad utilizzare innerHTML. createTextNode ci restituisce il riferimento al nodo di testo creato.

Il metodo appendChild inserisce il nuovo nodo. Come nel caso di innerText, con appendChild i tag non vengono interpretati come codice ma come semplice testo. L'unico problema è che questo metodo non rimpiazza il testo preesistente, ma inserisce il nuovo nodo alla fine della lista dei figli del nodo al quale è applicato. Questo problema è però presto risolto: prima di utilizzare il metodo ripuliamo il riquadro ponendo il suo innerHTML uguale a stringa vuota.

Vediamo ora come ritornare alla visualizzazione del testo formattato. Il procedimento è un po' più complesso.

Il metodo createRange crea un oggetto TextRange, che rappresenta un intervallo di testo.

Il metodo selectNodeContents imposta a un intervallo di testo di contenere il contenuto di un nodo. Quindi imposta al nostro oggetto TextRange il testo contenuto nel riquadro. Infine, convertendo il nostro oggetto in stringa, lo inseriamo all'interno del riquadro con il metodo innerHTML che già conosciamo.

Differenze nella creazione del codice HTML

Abbiamo visto come per arrivare agli stessi risultati in Mozilla e in Internet Explorer siamo dovuti riccorre a codici molto a sé stanti. Occorre a questo punto precisare, però, che la maggiore differenza tra i due browser è data dall'HTML generato nel documento editabile: mentre Internet Explorer produce i vari tag HTML (em, i, ecc.), Mozilla 1.3 genera tag di tipo span contenenti regole CSS.

Ad esempio se scriviamo nel riquadro di testo "HTML.IT" e clicchiamo sui tasti "Grassetto", "Corsivo" e "Sottolineato", con IE otterremo il seguente codice:

Mentre con Mozzilla avremo il più attuale:

<span style="font-weight: bold; font-style: italic; text-decoration: underline;">HTML.IT</span>

Ti consigliamo anche