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

Un sito personalizzabile in Javascript e CSS

Come consentire al visitatore del nostro sito di scegliere il layout che preferisce
Come consentire al visitatore del nostro sito di scegliere il layout che preferisce
Link copiato negli appunti

Una breve introduzione

Da almeno un paio di anni a questa parte i grandi portali hanno introdotto la "moda" di consentire ai propri utenti di scegliere i servizi da mettere nell'home page del sito, che diventa così "personalizzata": i visitatori interessati alla finanza possono così impostare la propria home page con grafici, quotazioni, indici di borsa, notizie; chi è attratto dallo sport può mettere in primo piano le ultime notizie dal campionato e eventualmente bacheche, club, o forum dedicati all'argomento.

Oltre ad essere un "vezzo stilistico"si tratta della necessità di razionalizzare i servizi di portali di grandi dimensioni in base alle esigenze dell'utente, in modo che quest'ultimo possa accedere subito alle risorse che maggiormente gli interessano, senza disperdere le forze in troppi click.

Se HTML.it offrisse un servizio di questo genere, il visitatore interessato alla grafica potrebbe mettere nella propria home page le guide a Photoshop, Flash, riferimenti a Font.it e Gifanimate.it e tutto quello che gli può essere utile per elaborare il layout dei siti, nonché un accesso diretto ai thread più interessanti del forum di grafica. Viceversa un programmatore si terrà a portata di mano mano i riferimenti a frephp.html.it, la guida di apache, java etc.

Dal punto di vista tecnico si tratta di impostare un database che associa a ciascun utente determinati campi che indicano le preferenze (ci sarà dunque una tabella di utenti a cui sono collegate diverse altre tabelle con le possibili scelte ). I dati vengono poi restituiti con un qualche linguaggio di programmazione lato-server, come asp, php, jsp, o perl.

In alcuni casi, oltre alla scelta dei servizi che l'utente può mettere in evidenza nella propria home page personalizzata, viene offerta anche la possibilità di personalizzare il layout del sito.


Personalizzare il layout di un sito

Senza ricorre a database e a complicati linguaggi di scripting server side in questo tutorial cercheremo di offrire all'utente la possibilità di personalizzare il nostro sito, scegliendo fra diversi layout. Per ottenere questo risultato utilizzeremo javascript e i fogli di stile, con particolare riferimento ai fogli di stile esterni e alle classi.

Si tratta di strumenti semplici, ma che hanno il vantaggio di essere indipendenti dal server su cui il sito si trova: si tratta dunque di un meccanismo che può funzionare correttamente anche su quegli spazi gratuiti che non supportano linguaggi di scripting server-side. A maggior ragione (e con minor fatica da parte del webmaster) questa tecnica è applicabile utilizzando linguaggi di scripting server-side (come asp, php, jsp)

Potremmo addirittura lasciare piena libertà al visitatore e consentirgli di scegliersi liberamente il colore delle scritte e degli sfondi, le dimensioni e la famiglia dei caratteri; decidere se utilizzare uno stile normale per il testo della pagina o piuttosto il corsivo o il grassetto. Così tuttavia si corre il rischio che l'utente visualizzi il nostro sito con uno sfondo verde-evidenziatore e scritte rosa-shocking. È preferibile dunque mantenere un certo controllo sul layout della pagina, offrendo al visitatore del nostro sito diverse opzioni di scelta, ma conservando pur sempre la padronanza dell'aspetto globale del sito.

Come funziona?

Dobbiamo realizzare un'interfaccia che ci consenta di:

  • mostrare al visitatore le diversi possibilità di scelta
  • memorizzare la sua scelta da qualche parte (noi lo faremo con un cookie - vedremo tra poco di cosa si tratta, per ora lo si consideri un contenitore in cui immagazzinare piccole quantità di dati)
  • le pagine del sito devono poi "leggere" la scelta e ri-adattare il layout di conseguenza

Potremmo dunque ideare un meccanismo di questo genere:

Nello schema:

  • nell'home page e nelle pagine interne compare il link "Scegli il layout", che rimanda alla pagina con l'anteprima dei diversi stili
  • cliccando sull'anteprima viene memorizzato immediatamente un cookie nel browser dell'utente che contiene la scelta effettuata
  • il cookie viene immediatamente letto dalla pagina stessa, che esegue il refresh di se stessa e quindi carica gli stili voluti
  • anche le altre pagine del sito si adeguano allo stile scelto
  • il cookie permane in memoria alle successive visite dell'utente

Da notare che con questo metodo non abbiamo finestre secondarie, ma solo una pagina contente l'anteprima dei differenti stili.

Utilizzare delle finestre di pop-up per visualizzare l'anteprima

Possiamo anche complicare leggermente le cose, ottenendo però un effetto più gradevole:

Nello schema:

  • Il link "scegli il layout" apre una finestra secondaria con le "thumbnail" del sito
  • Cliccando sull'immagine piccola si apre un'anteprima del layout desiderato (si tratta di una gif o di una jpg)
  • La pulsantiera sopra l'immagine consente all'utente scegliere fra diverse opzioni. Sono presenti i pulsanti "salva", "salva ed esci", "esci senza salvare", "chiudi tutto", "stile predefinito".
  • A seconda del pulsante scelto viene scritto il cookie (sono i pulsanti che contengono le voci "salva" e "stile predefinito") e le finestre vengono chiuse oppure vengono portate in primo piano.
  • La pagina principale viene portata in primo piano e viene ricaricata: il cookie viene letto e quindi il layout viene ri-elaborato in funzione della scelta dell'utente
  • La scelta rimane memorizzata anche per le altre pagine e per le successive visite nel sito

Questo schema tuttavia è più complesso del precedente per la difficoltà di passare i dati da una finestra all'altra. Nel corso dell'articolo non esamineremo questa situazione, che tuttavia è illustrata diffusamente negli esempi acclusi. Possiamo però anticipare che le tecniche per passare le variabili da una finestra all'altra sono molto simili a quelle che esamineremo per leggere il cookie.

Impostare gli stili

Per prima cosa dobbiamo creare il layout, che va pensato già nell'ottica della scelta dell'utente.
La pagina deve essere unica, perché se utilizzassimo pagine diverse a seconda del layout ci troveremmo poi in difficoltà nella gestione del sito (ogni correzione o aggiornamento andrebbe infatti riportata in tutti i file interessati).

Costruiremo quindi:

  • Un'unica pagina
  • Diversi fogli di stili esterni che attribuiscano diversi valori al layout della pagina (cambiando gli sfondi, il colore dei link, la dimensione e il tipo dei caratteri)

Nella nostra pagina le "parti comuni" a tutti i layout possono essere scritti in "semplice" HTML, o comunque possono rimanere nel corpo del documento. È invece necessario impostare una classe per quelle parti che variano a seconda del layout. Nei fogli di stile esterni troveremo poi diversi attributi per la medesima classe.

Sostanzialmente il contenuto del <body> della nostra pagina è lo stesso in tutto e per tutto in ogni layout (perché la pagina è sempre la medesima); la scelta tra un impostazione grafica e l'altra (o più esattamente tra un foglio di stile e l'altro) avviene invece tramite codice javascript impostato nella <head> del documento, che carica un foglio di stile o l'altro.

Personalmente consiglio di chiamare i vari fogli di stile "stile00.css", "stile01.css"; e le immagini "immagine00.gif", "immagine01.gif", in modo cioè che ad ogni stile o immagine corrisponda il numero d'ordine che lo contraddistingue. Questo infatti semplifica notevolmente le cose nella fase di elaborazione del codice javascript. Nulla vieta, tuttavia, di scegliere anche dei nomi più descrittivi (come "stileRosso.css", "logoVerde.gif") o quello che più si preferisce: vedremo in seguito come gestire anche quest'eventualità.

Memorizzare le variabili con javascript

Per quanto javascript non sia stato pensato per gestire ed elaborare il passaggio di dati da una pagina all'altra, ci sono tuttavia diverse tecniche che possono essere utilizzate a questo scopo:

  • I dati possono essere memorizzati nella barra degli indirizzi tramite il metodo "get" oppure simulando il riferimento a un'ancora (che invece è inesistente): l'URL della pagina assume quindi un aspetto di questo tipo: http://miosito.it/pagina.html?nomeVariabile=valore
    Oppure:
    http://miosito.it/pagina.html#nomeVariabile=valore
  • Possiamo creare un frameset con due frames, in cui uno occupa tutta la pagina e l'altro è praticamente nullo. In questo caso i parametri scelti dall'utente vengono memorizzati nel frame "invisibile".
  • Se esistono più finestre, è possibile memorizzare le scelte dell'utente facendo riferimento alle variabili contenute nell'una o nell'altra finestra. Ad esempio: nella finestra secondaria creo una variabile, la quale farà da contenitore per i parametri che individuano le scelte dell'utente nella finestra principale.
  • Possiamo creare un cookie che memorizzi le scelte dell'utente.

Qualunque sia la tecnica utilizzata per memorizzare i dati, bisogna tenere presente però che javascript non è nato per queste cose: in ogni caso si tratta di comporre delle stringhe, memorizzarle da qualche parte con qualche artificio (non importa se nella barra degli indirizzi, in un frame, in una finestra o in un cookie), per poi ri-scomporle ed estrarrare le variabili che ci servono. Risulta molto più semplice e più comodo fare la medesima cosa con perl, asp, php,o jsp, che hanno dei comodi metodi e delle funzioni pre-impostate per estrarre e scrivere le variabili.

Il cookie ("biscotto") è un piccolo insieme di informazioni che viene trasmesso dal server al client nelle intestazioni HTTP e che viene memorizzato in locale dal browser del utente in una directory apposita (i differenti browser hanno modi diversi per memorizzare i cookie).

Le informazioni sono date da una serie di variabili che assumono sempre questa forma e questa posizione:

nome=valore; expires=data ; path=percorso ; domain=dominio ; secure

Vediamo in dettaglio gli elementi che compongono un cookie:

  • nome=valore. Il nome del cookie è anche il nome della variabile che ci interessa inizializzare. Nel nostro caso il nome del cookie sarà "tipoStile" e il valore una stringa composta da due cifre ("00","01", eccetera).

    Per quel che riguarda il valore di un cookie, bisogna tenere presente che spazi bianchi, punti e virgola, o virgole non sono consentiti: se ci trovassimo mai nella necessità di dover utilizzare questi segni nel valore del cookie, dobbiamo anche ricordarci di codificarli in ISO-8859-1 (Latin-1) tramite il metodo escape.

    Se ad esempio voglio impostare un valore

    document.write("utente=Mario Rossi;");

    dovremo scrivere:

    document.write("utente="+escape("Mario Rossi")+";");

    che equivale a:

    document.write("utente=Mario%20Rossi;")

    per decodificare il valore dobbiamo poi ricordarci di utilizzare il metodo unescape.

  • expires=data. Se quest'attributo non viene impostato, il cookie vale solo per la sessione corrente: in pratica quando il browser viene chiuso il cookie viene cancellato. Impostare la data a " " è dunque anche il modo corretto per cancellare un cookie.

    La data va espressa sempre nel formato universale UTC ("Tempo Universale Coordinato": si tratta della data che fa riferimento a Greenwich. Fino a qualche tempo fa il formato in cui esprime tale data era il era il GMT). In ogni caso l'aspetto della data è questo:

    expires=Wed, 13 Nov 2002 01:09:51 UTC;

    Si tratta quindi di utilizzare il metodo Date.toUTCString() per convertire la data.

  • path=percorso. Se l'elemento path non viene espresso, il cookie ha valore solo a partire dalla directory in cui è stato creato.

    Ad esempio: un cookie creato in www.miosito.it/directoryPrincipale/directorySecondaria
    ha valore sulla /directorySecondaria/, ma non sulla /directoryPrincipale/.

    Viceversa il cookie in questione può essere correttamente letto in:
    www.miosito.it/directoryPrincipale/directorySecondaria/altraDirectory

    Per rendere il cookie valido a partire dalla root del dominio è sufficiente inzializzare il valore di path a " ". Così:

    path= ;

  • domain=dominio. Questo attributo ha come valore di default il nome dell'host del server web su cui risiede la pagina. Un cookie creato su "pro.html.it" ha dunque valore su tutto "html.it". per limitare il valore del cookie è necessario specificare:

    domain=pro.html.it ; Ovviamente non è possibile impostare dei cookie per server che non ci appartengono.

  • secure. Si tratta di un "flag" (cioè di una variabile booleana che indica uno stato, e in quanto tale può essere solo "true" o "false"). Specifica come il documento debba essere trasmesso: se l'indicazione "secure" è presente nel cookie, i dati devono essere trasmessi soltanto in presenza di connessione sicura (con https). Di default invece "secure" è impostato su "false" e i dati possono essere trasmessi con normale connessione "http"

La struttura di un cookie va rispettata rigidamente, altrimenti il cookie non verrà mai scritto. Ad esempio se si desidera impostare soltanto un nome e un valore per il cookie, e il dominio di riferimento, sarà necessario tuttavia ripetere anche le variabili intermedie, pur senza assegnare alcun valore. Così:

nome=valore; expires= ; path= ; domain=mioDominio.it ;

non è necessario invece impostare le variabili che seguono quella desiderata.

Bisogna però prestare attenzione e non abusare dei cookie, perché ci sono delle pesanti limitazioni:

  • il browser non è tenuto a memorizzare più di 300 cookie (in totale)
  • uno stesso server non può scrivere più di 20 cookie
  • ogni cookie non deve essere di dimensioni maggiori di 4 Kb

Per esercitarvi a scrivere i cookie e vederne immediatamente il risultato, potete utilizzare Netscape 6, che alla voce:

Edit > Preferences > Privacy & Security > Cookies > View Stored Cookies

mette a disposizione una comoda maschera per la gestione dei cookie, che vi permette di leggere i cookie, mentre li state creando.

Nel nostro sito dal link che consente all'utente di scegliere il layout, lanciamo la funzione che scrive il cookie, passandogli come parametro l'indicazione del layout scelto. Così:

<a href="javascript:scriviCookie('06')">
  <img src=".../.../miaIcona.gif">
</a>

La chiamata alla funzione fa riferimento - ovviamente - al codice che avremo preparato nella head, che a sua volta è finalizzato a comporre una stringa da inserire all'interno del cookie.

Questa stringa conterrà:

  • il tipo di layout scelto
  • la data di scadenza. Infatti, per far sì che l'utente ritrovi lo stesso tipo di layout alla sua successiva visita nel nostro sito dobbiamo prolungare la data di scadenza del cookie: arbitrariamente decidiamo di far scadere il cookie fra un anno.

La funzione che stiamo per scrivere dovrà quindi:

  • impostare la scadenza del cookie fra un anno
  • creare una stringa che contenga tutte le variabili necessarie al corretto funzionamento del cookie (notare che ci fermeremo a "path", dal momento che gli altri attributi non ci occorrono)
  • assegnare al cookie il valore della stringa
  • controllare che il valore della stringa sia stato effettivamente scritto: se non è così i cookie non sono abilitati nel browser dell'utente
  • fare il refresh della pagina

Per scrivere e leggere i cookie con javascript è sufficiente fare riferimento all'oggetto document.cookie, che restituisce tutti i cookie associati al documento corrente.

Vediamo il codice nei dettagli. Ecco la funzione scriviCookie, che richiede l'argomento layout:

function scriviCookie (layout)
{
dataFutura=new Date(); /*creo la data di oggi*/

/* prendiamo l'anno della data odierna tramite
   il metodo "getFullYear" e gli aggiungiamo "1" */
dataAnnoProssimo = dataFutura.getFullYear()+1;

/* partendo dalla data di oggi, inseriamo la data
   del prossimo anno, grazie al metodo "setFullYear"
   (che accetta - appunto - come argomento l'anno
   da impostare) */
dataFutura.setFullYear(dataAnnoProssimo);

/* convertiamo la data in una stringa adatta
   ad essere espressa nel cookie */
dataFutura=dataFutura.toUTCString();

/* A questo punto creiamo una stringa che contenga
   il valore del cookie. Notare che i valori della data
   e del layout sono variabili. Tutto il resto è "fisso".*/
contenutoCookie="tipoStile="+layout+"; expires="+dataFutura+ "; path= ;";

/* assegniamo al cookie il valore desiderato*/
document.cookie=contenutoCookie;

/* A questo punto verifichiamo che il cookie
   sia stato effettivamente scritto: il metodo
   "indexOf()" delle stringhe restituisce "-1" se
   la stringa cercata non è presente, altrimenti
   restituisce la posizione della stringa.
   Nelle righe seguenti cerchiamo dunque la posizione
   del nome del cookie ("tipoStile") che abbiamo appena
   scritto. Se il valore della posizione è uguale a "-1"
   il cookie non è presente, e quindi il browser dell'utente
   non è abiliato per ricevere i cookie */
if (document.cookie.indexOf("tipoStile=")==-1)
{
  alert ("Attenzione! devi abilitare i cookie!");
}

/* l'istruzione seguente esegue il refresh della pagina.
   Se nella pagina sono presenti le istruzioni necessarie
   a leggere il valore del cookie e impostare il layout,
   lo stile scelto viene caricato. */
self.location.reload();
}

Una volta scritto il cookie, si tratta di leggere le informazioni che abbiamo memorizzato. Il codice che segue va inserito all'inizio di ognuna delle pagine con il layout variabile.

Anche in questo caso interpelliamo l'oggetto document.cookie che contiene tutti i cookie associati al documento. Quindi - tramite il metodo indexOf() - cerchiamo la posizione di tipoStile. Se troviamo tipoStile estraiamo una sottostringa che contenga il valore del layout scelto dall'utente

cookies = document.cookie;

/* ricerchiamo all'interno del cookie del documento,
   la stringa "tipoStile=" e assegniamo il valore
   della sua posizione alla variabile "posStile" */
posStile = cookies.indexOf("tipoStile=");

/* se la stringa "tipoStile=" è presente
   (perché maggiore di "-1")...*/
if (posStile>-1)
{

/* cerchiamo il punto in cui finisce la stringa
   "tipostile="; per farlo prendiamo la posizione in
   cui si trova l'inizio di "tipoStile=" e gli aggiungiamo
   la lunghezza della stessa stringa "tipoStile=" */
fineStile = posStile+"tipoStile=".length;

/* Qui di seguito creiamo la variabile "stileScelto"
   che ci permette di individuare la scelta dell'utente.
   Il metodo "slice()" serve per estrarre la parte di una
   stringa, e ha come argomenti il punto di inizio e il
   punto finale */

/* "2" era la lunghezza della nostra variabile "layout"
   ("layout" poteva aver valore "00", "01", "02", ecc.);
   estraiamo una sottostringa composta dalla posizione
   finale di "tipoStile=" e dalla lunghezza della
   variabile. Dopodiché assegniamo il valore trovato
   a "stileScelto" */
stileScelto = cookies.slice(fineStile,fineStile+2);

} else {

/* in ogni caso - anche se "tipoStile non è presente"
   - assegniamo a stileScelto il valore di "00".
   Così, se il cookie non è trovato, viene assegnato di
   default questo valore. */
stileScelto="00";
}

Con questo codice dovremmo essere riusciti ad individuare la scelta dell'utente: elaborando il cookie, abbiamo infatti estratto la variabile "stileScelto", che contiene l'indicazione dello stile preferito dall'utente. "stileScelto" sarà quindi uguale a "00", "01", etc.

Da notare che in ogni caso, anche se il cookie "tipoStile" non è presente, la variabile "stileScelto" viene inizializzata con "00". Quest'assegnazione è assolutamente indispensabile: si tratta del valore di default. È il valore serve in ogni caso per visualizzare lo stile e si rivela indispensabile in determinate situazioni:

  • la prima volta che l'utente capita nelle nostre pagine, quando non è ancora presente nessun cookie (o se non è intenzionato a scegliere uno stile personalizzato)
  • nel caso in cui i cookie siano disabilitati

Scrivere il layout tramite le variabili: comporre delle stringhe

Ora che la pagina ha letto il valore del cookie, e ha assegnato il valore appropriato alla variabile "stileScelto" è relativamente facile parametrizzare il layout della pagina: si tratta di utilizzare il metodo document.write() per scrivere nel codice.

Se abbiamo chiamato i file "css" e le immagini con un nome che faccia riferimento al tipo di layout (ad esempio: "stile00.css", "logo00.gif", "immagine00.jpg"), è sufficiente scrivere l'inclusione degli stili e i riferimenti alle immagini come stringhe parametrizzate.

Nella head abbiamo quindi l'inclusione degli stili. Così:

document.write("<link rel="stylesheet" href="css/stile"+stileScelto+".css" type="text/css">");

Se nel <body> della pagina abbiamo immagini con una colorazione (o un anti-alias) particolare e vogliamo parametrizzarle, è sufficiente comporre con la stessa tecnica il percorso dell'immagine:

document.write("<img name="logo" src="../imgs/logo"+stileScelto+".gif" width="300" height="70" >");

Utilizzare l'istruzione "switch"

Se invece abbiamo utilizzato nomi di fantasia per fogli di stile è immagini, possiamo servirci di un'istruzione di switch per scrivere codice alternativo, a seconda del valore della variabile "stileScelto". In questo modo scriviamo sì più codice, ma siamo svincolati dai nomi rigidi dei file. Così:

/* All'interno dello switch assegniamo un diverso
   nome del file css alla variabile "mioStile", in
   base al valore di "stileScelto" */
switch (stileScelto) {

case "00":
mioStile="stileVerde.css";
break;

case "01":
mioStile="stileRosso.css";
break;

case "02":
mioStile="caratteriGrandi.css";
break;

/***eccetera***/

default:
mioStile="stileVerde.css";

}

/* alla fine scriviamo nuovamente il riferimento
   al foglio di stile esterno sotto forma di somma
   di stringhe: */

document.write("<link rel="stylesheet" href="css/ "+mioStile+" " type="text/css">");

Per le immagini - ovviamente - il procedimento è il medesimo.

Ulteriori problematiche

Siamo riusciti a portare a buon fine il nostro layout personalizzato a seconda dei gusti del visitatore e tutto in locale funziona alla perfezione. Se non fosse che, guardando le cose online, percepiamo un secondo (o un mezzo secondo) in cui il sito appare spoglio, nudo, e si ha la sensazione sgradevole di percepirne lo scheletro dell'HTML. Si tratta di quei pochi decimi di secondo in cui il codice javascript viene eseguito e avviene il passaggio da un foglio di stile all'altro.

A qualcuno tutto ciò sembrerà trascurabile. A qualcun altro sembrerà completamente inaccettabile.
Questo difetto lo percepiremo, non tanto se ci siamo limitati a impostare nei css diversi attributi per i caratteri (famiglia, colori, grandezze, eccetera), ma soprattutto se abbiamo utilizzato i css per impostare gli sfondi. Non c'è che dire, infatti: ricaricare un'immagine non è cosa immediata.
Che fare allora? Rinunciamo al nostro layout personalizzato?

Intanto non mi stancherò di ripetere che tutto quello che abbiamo visto finora può essere realizzato - con maggior stabilità e in maniera più semplice - con qualsiasi linguaggio di scripting server-side: e in quel caso non avremmo di questi problemi, dal momento che la pagina verrebbe completamente riprocessata...

Ma ovviamente esistono delle soluzioni anche in javascript.

Per esempio è possibile impostare una "maschera" che copra tutta la pagina fin quando questa non sia caricata. Si tratta di impostare un livello del colore dello sfondo, che abbia come dimensioni la larghezza e l'altezza della finestra, reso visibile, e messo in primo piano (quindi con uno z-index maggiore di quello del resto della pagina). Scriviamo la sintassi che descrive il livello subito dopo il tag <body>, di modo che sia la prima cosa ad essere "vista" dal browser.

In questo modo tutta la pagina viene coperta dal nostro "livello-maschera" e inizialmente non vediamo nient'altro che il colore del livello (che è lo stesso dello sfondo della pagina). Poi, quando tutto il documento è stata caricato (lanciamo cioè la funzione con l'evento OnLoad del <body>), cambiamo la visibilità del livello-maschera da "visibile" a "invisibile". E d'incanto apparirà il nostro sito con lo stile personalizzato che abbiamo scelto e senza errori o ritardi nella visualizzazione.

Non sviluppo il codice per il livello-maschera e la sua apparizione e sparizione, perché esula dal tema di questo tutorial. Si tratta comunque di una funzione tutto sommato abbastanza semplice che potete trovare un po' dappertutto. Se non avete voglia di scrivere il codice a mano, potete utilizzare anche qualche editor WYSIWYG (con Dreamweaver: Window > Behaviors > Show-Hide Layers).

Ti consigliamo anche