Come molti di voi sanno, jQuery è una libreria Javascript nata per
semplificare l'accesso agli oggetti del DOM dal lato del client e per realizzare delle
chiamate Ajax. Tra i suoi punti di forza annovera la possibilità di estendere le funzioni di base con dei plugin esterni.
L'obiettivo di questo tutorial è di creare un'interfaccia a tab con l'uso di JavaScript, di modelli CSS e di chiamate Ajax, in maniera semplice, impiegando una sola riga di codice Javascript nelle pagine HTML e sfruttando le potenzialità di jQuery. Per più complesse necessità segnalo che si può contare anche su un ottimo plugin come
jQuery.tabs.js
Premessa
I menu a "schede", o a "linguette", in inglese tab, consentono di
"nascondere" parti di testo di una pagina HTML, consentendo di snellire
la quantità di informazioni presentate: in un "box dei contenuti"
(di solito un container creato con la sintassi <div></div>
) si vedrà
un contenuto diverso a seconda della linguetta
attiva. Inoltre, vi sarà una sola linguetta attiva per volta, linguetta che avrà
un aspetto diverso dalle altre per identificare il suo stato.
L'interfaccia a tab richiede dunque che, dopo che l'utente ha cliccato su una
linguetta, uno script lato client - collegato all'evento onclick
-
esegua le seguenti attività:
- modificare l'aspetto della linguetta attualmente attiva, rendendola come non attiva;
- modificare l'aspetto della linguetta cliccata, mostrandola come attiva;
- sostituire nel "box dei contenuti" il contenuto corrente
con il contenuto associato alla linguetta attiva (oppure, a seconda
della logica seguita viene nascosto il "box dei contenuti" attuale e
mostrato il box associato alla linguetta attivata).
Normalmente i contenuti delle varie parti sono inseriti all'interno
della stessa pagina web in cui è presente la tab; con jQuery, si possono richiamare contenuti
di file esterni in modalità Ajax.
Relativamente alla parte CSS, un articolo che descrive queste tecniche è Un
menu a tabs con i CSS di Alessandro Fulciniti, o il più sofisticato Menu
con tab grafiche dello stesso autore. Una raccolta di interfacce
"tab-based" la troviamo nell'articolo
14 Tab-Based Interface Techniques.
Esempi problematici di interfacce a tab
Mentre stavo scrivendo questo tutorial mi sono imbattuto in due diverse realizzazioni di
interfacce a tab:
- Creating a Tabbed Interface with CSS and jQuery di
Rob Maurizi (demo) - Tabmenu for free di Koller Jürgen, che ne fa un uso esteso sul suo sito,
in maniera davvero efficace ed espressiva (demo)
Si tratta di implementazioni apparentemente semplici. Tuttavia, andando ad
esaminarle in dettaglio, ci accorgiamo che queste due interfacce
intervengono direttamente sul codice HTML e non possono essere facilmente estese, se
non in maniera problematica. Si tratta cioè di soluzioni intrusive, che
mescolano assieme senza separarli HTML, CSS e Javascript (sulla questione potete
approfondire il concetto con il corso "Unobtrusive
Javascript" di Christian Heilmann -tradotto anche in italiano- ed anche esaminando le tecniche descritte
nell'articolo "Il
problema di window.onload" di Peter Michaux).
Vediamo, dapprima, come Koller Jürgen realizza il suo pannello a tab, che
tralasciando gli altri dettagli, è definito da una lista come segue:
<div class="menu">
<ul>
<li><a href="#" onmouseover="blendon('tabcontent1'); blendoff('tabcontent2');
blendoff('tabcontent3');blendoff('tabcontent4'); swichtabs('1');" onclick="return
false;" title="" class="tabactive" id="tablink1">Tab 1 </a></li>
<li><a href="#" onmouseover="blendon('tabcontent2'); blendoff('tabcontent1');
blendoff('tabcontent3');blendoff('tabcontent4'); swichtabs('2');" onclick="return
false;" title="" id="tablink2">Tab 2 </a></li>
<li><a href="#" onmouseover="blendon('tabcontent3'); blendoff('tabcontent1');
blendoff('tabcontent2'); blendoff('tabcontent4'); swichtabs('3');" onclick="return
false;" title="" id="tablink3">Tab 3 </a></li>
&<li><a href="#" onmouseover="blendon('tabcontent4'); blendoff('tabcontent1');
blendoff('tabcontent2');blendoff('tabcontent3'); swichtabs('4');" onclick="return
false;" title="" id="tablink4">Tab 4 </a></li>
</ul>
</div>
Le funzioni blendon
e blendoff
vanno ad attivare o
disattivare le linguette, mentre la funzione swichtabs
aggiorna
il contenuto del box dei contenuti. Rimando alla
demo
per i dettagli. Come si vede, se dobbiamo scrivere 3 tab o 7 tab dobbiamo
riscrivere completamente tutto il codice, e la cosa può diventare pesante.
Invece, lo script di Rob Maurizi, interviene con un codice Javascript che fa
uso di jQuery per attivare la linguetta ed il contenuto:
$(document).ready(function() {
$("#program_details dd").hide();
$("#program_details dt").click(function() {
var tgt = $(this).attr("target");
$("#program_details dd:visible").hide();
$ ("#program_details dt.tab_here").removeClass("tab_here");
$("#"+tgt).show();
$(this).addClass("tab_here");
});
});
Anche in questo caso, esaminando la parte HTML, vediamo che si
tratta di un'implementazione ancora meno generalizzabile. Ne riportiamo un
frammento:
<div id="program_detail_tabs">
<dl id="program_details">
<dt target="pg_overview" id="tab_overview">Overview</dt>
<dd style="display: none;" id="pg_overview">This is how you could create .....</dd>
<dt class="tab_here" target="pg_works" id="tab_works">How it Works</dt>
<dd style="display: block;" id="pg_works">Starting out with a basic .....</dd>
.............
</dl>
</div>
Come si vede dobbiamo dare un id
diverso a ciascuna tab, e poi abbiamo
molti box dei contenuti (gli elementi <dd>
della lista), ciascuno a sua
volta con id
differente.
La mia soluzione
Utilizzando appieno le potenzialità di jQuery ho
realizzato un'interfaccia a tab molto più generale (esempio). L'esempio
mostra anche una modalità di implementazione di una
funzione codeview, cioè di visualizzazione di codice CSS, JS, HTML richiamabile dall'interfaccia tab-based.
Vediamo subito l'esempio nella sua struttura HTML:
<div id="tab-menu">
<ul>
<li><a href="#Commento">Commento</a></li>
<li><a href="tabshort.css">Mostra tabshort.css</a></li>
<li><a href="jquery.tabshort.js">Mostra jquery.tabshort.js</a></li>
<li><a href="tabshort-demo.html">Mostra tabshort-demo.html</a></li>
</ul>
<div id="tab-contenuto"></div>
</div>
<div class="contenutoNascosto" id="Commento">
Questo tab non ha un contenuto Ajax attivo, <br />
gli altri tab aprono un file esterno....<br />
Il blocco div deve essere esterno al div del tab
</div>
L'interfaccia a tab è contenuta all'interno di <div id="tab-menu"></div>
.
Volendo possiamo avere più menu a tab nella stessa pagina: basta usare un id
diverso. All'interno del container <div id="tab-menu"></div>
troviamo una lista, più il box dei contenuti <div id="tab-contenuto">
.
Nella lista <ul>
avremo tanti elementi <li>
ciascuno contenente un link. Il testo è quello che sarà mostrato sulla
linguetta, l'url invece può essere:
- # o vuoto, ed in questo caso viene mostrato solo un
messaggio di errore nel box dei contenuti - #miaetichetta, ed in questo caso nel box dei contenuti sarà
richiamato un contenuto interno alla stessa pagina associato ad una div
avente l'id miaetichetta - url, ed in questo caso nel box dei contenuti sarà richiamato un
contenuto esterno tramite una chiamata Ajax; ricordo che jquery - per motivi
di sicurezza - consente di richiamare via Ajax solo pagine esterne contenute
nello stesso dominio e nella stessa cartella della pagina che effettua la
chiamata; nell'esempio realizzato il codice javascript riconosce
l'estensione del file esterno e attiva dei comportamenti diversi secondo che
si tratti di estensioni .css, .txt, .js, htm, html, asp, php, consentendo di
realizzare una comoda funzionalità codeview.
All'esterno di <div id="tab-menu">
avremo tanti div
come <div class="contenutoNascosto" id="Commento">
.
Si tratta di contenuti che normalmente sono nascosti, fino a quando cliccheremo sulla linguetta
associata. Nell'esempio, il primo elemento della lista ha un link con l'url
#Commento
al quale corrisponde come contenuto quello del div con l'id Commento
.
Lo script che fa funzionare l'interfaccia tab-based è indipendente dalle
scelte di stile. Normalmente, infatti, si pone lo stile in un file CSS esterno. Nel nostro
esempio ciascuna regola di stile è legata direttamente a <div class="contenutoNascosto">
:
#tab-menu{
border-bottom: 1px solid gray;
/width: 90%;
margin-bottom: 1em;
}
#tab-menu ul{
padding: 3px 0;
margin-left: 0;
margin-top: 1px;
margin-bottom: 0;
font: bold 12px Verdana;
list-style-type: none;
text-align: left;
}
..........
Se abbiamo più interfacce tab-based sulla stessa pagina è forse più
conveniente riferirsi ad una classe nel foglio stile come, ad esempio:
.tab-menu-class{....}
.tab-menu-class ul{.....}
..........
classe che però va assegnata al div che definisce l'interfaccia:
<div id="tab-menu" class="tab-menu-class">
<ul> .....
</ul>
<div id="tab-contenuto"></div>
</div>
.....
Questa soluzione è mostrata nel secondo esempio.
Vediamo ora come è organizzato lo script che opera dietro la pagina e che è
contenuto nel file jquery.tabshort.js. Nella sezione <head>
della
nostra pagina HTML richiameremo questo script e la libreria jQuery come segue:
<script type="text/javascript" src="../js/jquery.pack.js"></script>
<script type="text/javascript" src="jquery.tabshort.js"></script>
Le funzioni presenti in jquery.tabshort.js sono le seguenti:
- GestioneClickSuTab()
- AttivaTab()
- MostraContenuto()
Cosa fanno le varie funzioni è evidente da quanto abbiamo detto in premessa.
Inoltre, in jquery.tabshort.js abbiamo alcune funzioni accessorie e la funzione che viene eseguita per inizializzare la tab - InizializzaTab
- quando la pagina è interamente caricata
(esempio):
$(document).ready(function() {
InizializzaTab ('tab-menu');
InizializzaTab ('tab-menu2');
});
Lo script può essere semplificato se non interessa realizzare la funzione codeview, in particolare la funzione MostraContenuto,
oppure può essere esteso, ad esempio per aggiungere effetti di animazione. Ma in questo caso conviene usare direttamente il plugin
jQuery.tabs.js,
di cui parleremo in un prossimo articolo.
Tutti gli esempi, completi delle librerie usate, sono disponibili per il download.