Cambiare lo stile al volo con CSS e DOM
di Francesco Castronovo, 02 Gennaio 2004
Indice del Tutorial
2. Lo Script
3. In Pratica
- Preparare la pagina
- Un esempio
- Il file ZIP con tutti i file dell'esempio
1. Teoria e definizioni
L'oggetto style e l'attributo class
Come descritto nella sezione DHTML del DOM, I browser compatibili con DOM supportano l'oggetto style.
L'oggetto style è stato proposto da Microsoft ed è diventato uno standard nel CSS2 di DOM. Attraverso l'oggetto style, i browser DOM permettono di modificare qualsiasi stile.
Sintassi
La sintassi è semplice. Per riferirsi ad una classe basta scrivere:
element.style.styleName
Quasi tutti gli stili sono accessibili in lettura/scrittura, anche se alcuni browser non possono cambiare alcuni stili come position.
Nel DOM, se il nome di stile consiste di due o più parole separate dai trattini '- ', rimuovere il trattino e capitalizzare la prima lettera della parola che la segue.
Per esempio:
background-color = > backgroundColor
Il DOM W3C fornisce un'alternativa a quella descritta nella sezione DHTML. L'attributo della classe dell'elemento può essere cambiato così:
element.className = newClassName
La Collezione dei Fogli di stile del documento (stylesheets)
Microsoft per primo ha fornito la collezione document.styleSheets. Il W3C la ha adottata nel CSS Livello2 del DOM. In questa collezione sono disponibili tutti i fogli di stile, anche se l'attributo rel è settato su "alternate stylesheet".
Il DOM permette di cambiare un intero foglio di stile. Per riferirsi ad un foglio di stile specifico, basta usare:
document.styleSheets[indexOfStyleSheet]
Usando stylesheet.rules o la collezione stylesheet.cssRules, alcuni browser permettono di modificare gli stili, ed anche di generare o rimuovere le regole. Tuttavia, il supporto è ancora limitato.
Modificare lo stile tramite l'href di un foglio di stile collegato
L'href del foglio di stile può essere letto in alcuni browser usando la proprietà HREF.
Mozilla, Safari, Opera 7+ e Internet Explorer 5+ possono settare l'href del tag LINK usando il setAttribute e Internet Explorer 4+ può anche regolare l'href tramite styleSheets[index].
Modificare lo stile tramite il menu "visualizza" del browser
Mozilla e Opera 7+ permettono agli utenti di scegliere i fogli di stile alternativi nel menu "visualizza".
Tuttavia, questa scelta non è memorizzata dal browser, così che l'utente dovrà scegliere per ogni pagina che visita sul sito.
Inoltre, browser come Internet Explorer e Safari non permettono che l'utente scelga i fogli di stile in alcun menu, così da dover usare il DOM per cambiarli manualmente.
Si noti che usando il menu "visualizza" o il DOM, i fogli di stile che hanno lo stesso titolo vengono commutati insieme e come se fossero un unico foglio di stile.
Il menu di "visualizza" permette soltanto di selezionare i fogli di stile in cui i titoli sono identici. Se voleste permettere delle combinazioni, dovreste produrre fogli di stile uniti o includere gli stessi temi multipli del foglio con differenti titoli per ogni combinazione.
Compatibilità della commutazione dei fogli di stile
- supportato correttamente da IE 4+, MAC per IE5+ e da GECKO (NETSCAPE 6+, MOZILLA ecc.)
- supportato quasi correttamente da MAC di IE 4
- supportato correttamente da OPERA 7+, usando una sintassi differente
I fogli di stile possono essere abilitati o disabilitati in alcuni browser usando la proprietà disabled (booleana), ma alcuni browser permetteranno di cambiare la proprietà disabled soltanto se esiste l'attributo di TITLE nel Tag LINK.
2. Lo script
Per garantire il funzionamento con tutti i browser sopra menzionati, Opera 7+ incluso, la funzione in Javascript abilita/disabilita i fogli di stile soltanto se l'attributo di TITLE e stato assegnato.
Spesso, questa tecnica può essere abbinata all'utilizzo dei cookies, per memorizzare le preferenze degli utenti quando lasciano una pagina (tramite l'evento onunload), e ripristinare il tema prescelto alla pagina successiva (tramite l'evento onload).
Ciò è il problema principale per la maggior parte degli script di base che ho trovato per la commutazione dei fogli di stile.
Lo script di cui trattiamo permetterà invece di commutare anche delle combinazioni dei fogli di stile alternativi.
Come riferirsi alle proprietà disabled e title dei fogli di stile
Metodo 1:
La regolazione della proprietà disabled permette l'abilitazione/disabilitazione di un particolare foglio della collezione e l'attributo di TITLE è disponibile come proprietà di Javascript.
- Internet Explorer 4+ e mac 5+ supportano questa tecnica
- Gecko (Netscape 6+, Mozilla ecc.) sostiene correttamente document.styleSheets
- Opera 7 non supporta affatto questa collezione
Metodo 2:
L'equivalente a document.styleSheets può ottenersi riferendosi ai relativi tag STYLE e LINK. La proprietà disabled può essere letta e modificata e l'attributo di titolo è disponibile. Dovrete assicurarvi che i tag LINK siano usati per importare li fogli di stile controllando il loro attributo "REL" poichè LINK ha svariati usi.
- Internet Explorer 4+ supporta questa tecnica, ma fin quando non si setta la proprietà disabled con Javascript, essa risulterà falsa, anche se l'attributo "rel" è precisato come "alternate stylesheet" e quindi il foglio di stile è disabilitato
- MAC per Internet Explorer 4+ sostiene correttamente questa tecnica
- Gecko (Netscape 6+, Mozilla ecc.) sostiene correttamente questa tecnica
- Opera 7+ supporta questa tecnica, ma fino a regolare la proprietà disabled con il Javascript, risulterà falsa, anche se l'attributo "rel" è precisato come "alternate stylesheet" e quindi il foglio di stile è disabilitato. Inoltre, i cambiamenti operati tramite il menu "visualizza" si perdono alla pagina successiva
Il codice:
Anche se sarebbe auspicabile poter usare la tecnica raccomandata del W3C, lo script deve usare anche il metodo dell'atributo TITLE della collezione LINK, per garantire la compatibilità con Opera 7.
Ecco il codice dello script:
// La funzione per cambiare i fogli di stile function templateChange(){ //controllo browser if(!document.styleSheets){ var ss = getAllSheets() //Opera }else{ var ss = document.styleSheets; //Dom } // disabilita tutti i fogli di stile con un titolo // tranne quello passato per argomento alla funzione for( var x = 0; x < ss.length; x++ ) { if( ss[x].title ) { ss[x].disabled=true; } for( var y = 0; y < arguments.length; y++ ) { //controlla ogni titolo ... if(ss[x].title == arguments[y]){ //e riabilita il foglio di stile se ha il titolo scelto ss[x].disabled=false; } } } if( !ss.length ) { alert( 'Il tuo browser non è abilitato a cambiare i fogli di stile CSS' ); } } // --------------------------------------------------------------------------------- // Funzione per Opera function getAllSheets(){ if( document.getElementsByTagName ) { var Lt = document.getElementsByTagName('LINK'); var St = document.getElementsByTagName('STYLE'); } else { // browser minori - restituisce array vuoto return []; } //per tutti i tag link ... for( var x = 0, os = []; Lt[x]; x++ ) { //controlla l'attributo rel per vedere se contiene 'style' if( Lt[x].rel ) { var rel = Lt[x].rel; } else if( Lt[x].getAttribute ) { var rel = Lt[x].getAttribute('rel'); } else { var rel = ''; } if(typeof(rel)=='string'&&rel.toLowerCase().indexOf('style')+1){ //riempe la variabile os con i stylesheets linkati os[os.length] = Lt[x]; } } //include anche tutti i tags style e restituisce l'array for( var x = 0; St[x]; x++ ) { os[os.length] = St[x]; } return os; } // --------------------------------------------------------------------------------- // Questa funzione è soltanto accessoria e serve nel caso preferiate gestire // la commutazione tramite una select nel documento, come nell' esempio function temaChange(selObj){ if(selObj.selectedIndex == 0){ // disattiva tutti gli stili con il title templateChange(); }else{ // attiva soltanto lo stile scelto eval("templateChange('"+selObj.options[selObj.selectedIndex].value+"')"); } }
3. In pratica:
Preparazione della pagina HTML
Il documento va preparato come segue:
3.1 Stile globale
In primo luogo, specificare uno foglio di stile persistente con tutti gli stili globali, usando:
< link rel="stylesheet" type="text/css" href="globale.css">
Non avendo attributo title, esso verrà usato sempre e non potrà essere disabilitato.
Non è indispensabile crearlo, ma se lo fate, ricordatevi che verrà utilizzato in tutte le combinazioni e sarà utilizzato insieme a qualsiasi foglio commutiate successivamente attraverso questo metodo.
3.2 Stile predefinito
Poi create un foglio di stile preferito che si andrà ad aggiungere a quello globale (secondo il "meccanismo a cascata" del Css2), che garantirà un aspetto predefinito di base per i browser che non possono commutare gli stili:
< link rel="stylesheet" type="text/css" href="default.css" title="Default">
3.3 Stili alternativi
Infine definite dei fogli di stile alternativi nel documento nel seguente modo:
<link rel="alternate stylesheet" type="text/css" href="stile1.css" title="Stile1">
<link rel="alternate stylesheet" type="text/css" href="stile2.css" title="Stile2">
<link rel="alternate stylesheet" type="text/css" href="stile3.css" title="Stile3">
Poiché questi fogli di stile sono definiti usando "alternate stylesheet" per l'attributo"rel", nei browser che non possono commutare i fogli di stile essi saranno disabilitati in partenza.
3.4 Lo script
Inserire lo script nel documento
<script type="text/javascript" src="dyntema.js"></script>
3.5 La funzione
Richiamare la funzione tramite un evento, come nell'esempio:
<body onload="templateChange('Stile1','Stile2');">
3.6 Usare una select
Per comodità ho incluso nella script una funzione accessoria per gestire la selezione dello stile tramite una SELECT nella pagina, in queso caso, la funzione richiamata è:
temaChange('Stile1')
Esempio
L'uso classico di questa funzionalità è quella di permettere ai visitatori di un sito di scegliere un tema grafico tra quelli disponibili secondo le loro preferenze, come potete vedere nel seguente esempio (Link esterno a gdesign.it).
File ZIP
Questo file ZIP scaricabile (4 Kb) contiene lo script e una pagina d'esempio.
:: Pagina stampata da http://www.gdesign.it ::
