Dall’HTML al jQuery: come mostrare/nascondere dei box in una pagina web?

Prendendo spunto dalla richiesta di un lettore ho pensato di realizzare questo esempio per mostrare il processo di creazione di una sezione di un sito, dalla struttura HTML fino all’integrazione di jQuery. Vediamo quindi in questo articolo come realizzare una pagina di Domande frequenti (FAQ).
La struttura HTML
La prima cosa che devi fare è chiederti come devono essere mostrate le informazioni quindi, nel caso specifico, quali tag utilizzare. Cosa dobbiamo realizzare? Una serie di domande seguite dalle relative risposte.
Quando hai una serie di elementi da mostrare nel 99% dei casi devi utilizzare una lista. Quindi la scelta si riduce a:
- Lista ordinata
- Lista non ordinata
- Liste di definizione
Nel nostro caso specifico, vogliamo rappresentare un elenco qualsiasi di domande, quindi l’ordine relativo non è importante. Potremmo utilizzare le liste di definizione, ma il rapporto semantico che c’è tra domanda e risposta, secondo me, non è esattamente come quello tra termine e definizione. Resta quindi come scelta definitiva una lista non ordinata.
<ul> <li>...</li> <li>...</li> ... </ul>
Bene, abbiamo così ottenuto l’involucro esterno. In ogni elemento della lista dobbiamo inserire una domanda e una risposta. Che tag utilizzare?
La domanda è quello che da specificità all’elemento, quindi io la vedrei ben rappresentata da un’intestazione. Il livello dipenderà dal caso particolare ma, considerando che il tag h1 viene di solito utilizzato per il nome del sito e il tag h2 per i titoli delle pagine, possiamo con buona approssimazione pensare di utilizzare un’intestazione di terzo livello:
<ul>
<li>
<h3>Domanda</h3>
....
</li>
<li>
<h3>Domanda</h3>
....
</li>
...
</ul>
Le risposte purtroppo possono essere di natura molto varia, quindi comprendere paragrafi, liste, tabelle, immagini e quant’altro. Non possiamo quindi associare a queste un tag specifico.
<ul>
<li>
<h3>Domanda</h3>
<p>....</p>
</li>
<li>
<h3>Domanda</h3>
<table>...</table>
</li>
...
</ul>
Questo modo di strutturare il codice prende il nome di compound (che tradotto significa “composto”): infatti abbiamo composto in una struttura significativa vari tag.
Ecco il risultato di questa prima fase del nostro lavoro: come puoi vedere, anche senza alcuno stile applicato, le coppie domanda/risposta sono ben visibili.
Applicare gli stili CSS
Devo ammettere, però, che anche per uno sviluppatore una pagina FAQ così è un po’ spoglia. Applichiamo un foglio di stile alla pagina, in modo da renderla più presentabile.
La prima cosa che faccio di solito è quella di azzerare tutti gli stili interni del browser. Esistono “fogli di reset” già pronti, come quello realizzato da Eric Meyer oppure da Yahoo, anche particolarmente complessi; per questa occasione basterà azzerare margini e padding di ogni elemento.
* {
margin:0;
padding:0;
}
...
Il prossimo passo sarà quello di centrare la struttura, dando una dimensione fissa al body e margini laterali calcolati automaticamente. Specifichiamo poi un colore di sfondo e lo stile globale del testo (non dimenticare mai di specificare l’interlinea!):
...
body{
background-color:#036;
color:#fff;
font: small/1.4 Helvetica,Arial,sans-serif;
margin:0 auto;
width:960px;
}
...
Questo è il risultato a cui siamo arrivati. Nota come ho inserito le regole in ordine alfabetico: questo mi permette di fare uno scanning più veloce del testo, in fase di ricerca.
Il risultato non è però dei migliori: l’azzeramento dei margini ha avvicinato tutti gli elementi, rendendoli difficoltosi da leggere. Proseguiamo nella nostra opera, modificando l’aspetto della lista delle domande. Per assicurarci di applicare gli stili solo a questa lista, applichiamo un ID all’elemento ul:
<ul id="faq">
<li>
<h3>Domanda</h3>
<p>....</p>
</li>
<li>
<h3>Domanda</h3>
<table>...</table>
</li>
...
</ul>
Applichiamo uno sfondo agli elementi li, eliminiamo i punti d’elenco applicati di default dal browser, e diamo un po’ di margini:
...
#faq > li{
background-color:#69C;
list-style-type:none;
margin-bottom:10px;
padding:5px;
}
...
Quello che resta da fare è modificare l’aspetto delle domande, in modo da farle risaltare rispetto alle risposte: gli utenti scorreranno la pagina passando rapidamente da una domanda all’altra, soffermandosi così solo su quella di loro interesse:
...
#faq h3{
background-color:#369;
color:#FFF;
padding:5px;
padding-left:20px;
}
...
Il risultato non è per niente male: certo si potrebbe realizzare qualcosa di più elaborato, ma rende perfettamente l’idea.
Come rendere il tutto più interessante con jQuery?
Le nostre FAQ sono certamente ben strutturate, hanno un aspetto accettabile, ma sono un po’ “statiche”, non trovi? Possiamo renderle più interessanti utilizzando jQuery: nasconderemo le risposte che verranno mostrate solo al clic sulla domanda relativa.
La prima cosa da fare è includere jQuery e creare un nuovo file. Il passo successivo è quello di nascondere tutti gli elementi di ogni voce della lista, tranne le domande. Per far ciò utilizzeremo un selettore speciale incluso in jQuery: :not. Questo selettore seleziona tutti gli elementi tranne quelli passati come argomento. Ad esempio:
$(":not(p)").hide();
permette di nascondere tutti gli elementi tranne i paragrafi. Applichiamo questo selettore alle nostre FAQ:
$(document).ready(function(){
$("#faq li > *:not(h3)").hide();
});
L’effetto è più che soddisfacente. Adesso non rimane che applicare l’azione mostra/nascondi al titolo. Per far questo utilizziamo la funzione click, utilizzando le variabili per rendere il codice più leggibile:
$(document).ready(function(){
$("#faq li > *:not(h3)").hide();
$("#faq h3").click(function (){
//selezioniamo tutte le risposte
var risposta = $(this).siblings();
//mostriamo/nascondiamo le risposte
risposta.slideToggle("slow");
});
});
Il codice è molto semplice: prima associamo l’evento click alle domande (#faq h3) poi selezioniamo la risposta, utilizzando la funzione siblings di jQuery, che seleziona tutti gli elementi dello stesso livello di quello considerato; infine attraverso la funzione slideToggle mostriamo/nascondiamo la nostra selezione. Il risultato è perfettamente funzionante, ed è esattamente ciò che volevamo ottenere.
Possiamo fare ancora di meglio, però. Ad esempio gli utenti non hanno nessun feedback visivo della cliccabilità dei titoli: a loro appaiono semplici testi! Potremmo applicare un puntatore diverso tramite css, però poi sarebbe visibile anche nel caso di JavaScript non abilitato. La cosa migliore è quindi applicare tale puntatore sempre tramite JavaScript, sfruttando il concatenamento fornito da jQuery:
$(document).ready(function(){
$("#faq li > *:not(h3)").hide();
$("#faq h3").css("cursor","pointer").click(function (){
//selezioniamo tutte le risposte
var risposta = $(this).siblings();
//mostriamo/nascondiamo le risposte
risposta.slideToggle("slow");
});
});
Aggiungiamo poi un altro elemento visivo, un piccolo “più”, che suggerisce la possibilità di espansione dei vari elementi. Lo applicheremo come sfondo delle domande, tramite CSS:
...
#faq h3{
background:#369 url('../img/plus.gif') center left no-repeat;
color:#FFF;
padding:5px;
padding-left:20px;
}
...
Questo è ciò che abbiamo ottenuto. L’usabilità è sicuramente aumentata: ora è chiaro che ogni domanda nasconde la relativa risposta, e che è possibile cliccare per ottenerla. C’è solo un ultimo dettaglio fuori posto: il simbolo accanto alla domanda è sempre un “più” anche quando la risposta è mostrata: in questi casi vorremmo che si trasformasse in un “meno”.
Dobbiamo modificare il nostro script, in modo tale che lo sfondo della domanda cambi a seconda dello stato della risposta:
$(document).ready(function(){
$("#faq li > *:not(h3)").hide();
$("#faq h3").css("cursor","pointer").click(function (){
var domanda = $(this);
//Immagine di sfondo: meno
var minus = {
'background-image':'url(img/minus.gif)'
};
//Immagine di sfondo: più
var plus = {
'background-image':'url(img/plus.gif)'
};
//selezioniamo tutte le risposte
var risposta = domanda.siblings();
//se la risposta è nascosta mettiamo come sfondo
//il più, altrimenti il meno
if (risposta.is(':hidden')){
domanda.css(minus);
}
else{
domanda.css(plus);
}
//mostriamo/nascondiamo le risposte
risposta.slideToggle("slow");
});
});
La cosa importante di questa modifica è l’aggiunta del blocco “if-else”, che sfrutta il selettore speciale :hidden: quest’ultimo seleziona tutti gli elementi nascosti, e viene passato come argomento alla funzione .is(). Quindi se l’elemento è nascosto, associamo l’immagine di sfondo “più”, tramite la funzione .css(), altrimenti assegniamo il “meno”.
L’ultima accortenza è quella di rendere l’animazione più fluida: come puoi notare tutti gli elementi della risposta vengono animati, provocando un effetto “stretched”. Questo è dovuto al fatto che jQuery effettua l’animazione scelta su ogni elemento e non sul blocco. La soluzione è molto semplice: tramite JavaScript racchiudere la risposta in un div aggiuntivo, in modo da rendere l’animazione più scorrevole.
La funzione che utilizziamo per questo scopo è wrapAll che, come suggerisce il nome, “avvolge” tutti gli elementi nel tag passato come argomento. Noi vogliamo un semplice div, quindi passeremo questa stringa come argomento:
$(document).ready(function(){
$("#faq li > h3").each(function(){
$(this).siblings().wrapAll('<div>');
});
...
Ecco finalmente il risultato finale.
Considerazioni finali
Ci sono diversi punti che mi preme sottolineare: abbiamo visto come il processo sia partito da semplice HTML, a cui è stato applicato un foglio di stile, e solo in ultima battuta abbiamo aggiunto gli effetti tramite jQuery. Questa tecnica è nota come progressive enhancement. Questo fa si che la nostra pagina sia accessibile e fruibile sia che l’utente navighi con un browser moderno, piuttosto che con un browser testuale o obsoleto, o ancora utilizzando uno screen reader.
Questo concetto di sovrapposizione di struttura, aspetto e azione è fondamentale in un panorama ampio come il web dei giorni nostri, in cui gli utenti possono accedere alle nostre pagine dai client più disparati.
Puoi scaricare i file del modulo FAQ e modificarli/adattarli alle tue esigenze e, perché no, condividere le tue modifiche con noi.
Potresti essere interessato anche ai seguenti articoli:
19 commenti
Trackback e pingback
Nessun trackback o pingback disponibile per questo articolo.





Bel post (e bel sito)! jQuery è davvero “cool”…
Ciao @jp
benvenuto su YIW e grazie (a nome di tutta la redazione).
In effetti, grazie a jQuery, una volta eliminate tutte le differenze di gestione JavaScript tra i vari browser, ci si può concentrare solo su quello che si deve realizzare ed è molto più produttivo
eheheh, chissa a quale lettore ti riferisci.. eheheh sono contento che le mie domande possono servire da spunto per creare nuovi articoli che, grazie a voi, vengono trasformati in tutorial ben realizzati e che servono di aiuto a molti web designer e non solo.
per il momento mi diletto a creare siti web con particolare attenzione all’usabilità e al lato seo/marketing e devo dire ch emi riesce molto bene
)
Comunque tornando a noi grazie mille per l’articolo mi è servito molto. Davvero complimenti pe rla pulizie del codice.
Io ho da poco finito il corso di web design durato due anni purtroppo è stato orientato molto sul design html e css e poco dal lato ‘programmatore’, pero la mia passione mi spinge ad imparare cose nuove e la mia curiosità mi spinge a non pormi limiti. Spro un giorno posso diventare bravo come te.
Comunque oltre a condividere i vostri articoli tramite twitter adesso inserirò il vostro link mel blog roll del mio blog
ciao e grazie ancora continuate cosi
@GrAfIcAnDo
)
Io (ma credo di poter parlare a nome di tutti gli autori) credo che una comunità sia basata sulla condivisione e sul dialogo. Noi scriviamo affinché voi leggiate, e viceversa.
Se un lettore mi chiede un approfondimento su un argomento perché non farlo? (naturalmente sempre nel caso rientri nelle mie capacità
Complimenti per il tuo percorso, continua a studiare, e vedrai che i frutti arriveranno. E grazie per la pubblicità
A presto
Ciao, intanto grazie per queste lezioncine, non sono pratico di JQuery ma trovo i articoli moltocomprensibili.
Non ho capito solo un punto, come mai nella versione finale, l’animazione dello scroll dowv è differente dalle precedenti? è un metodo che dai tu o non si può definire il tipo di movimento?
mi spiego, negli esempi fono al penultimo le righe delle risposte si animano in modo indipendente, mentre nell’ultimo tutto il paragrafo compare assieme.
@IlDottorBruZzani
Ciao e benvenuto su YIW.
Grazie per avermi fatto notare questo punto: è stato un mio errore (avevo mancato un paragrafo). Adesso è tutto a posto.
Grazie ancora
Complimenti è un effetto che mi sarebbe stato molto utile con un mio vecchio lavoro.
Ho visto l’esempio, non credi che quando si clicca su una delle domande sarebbe meglio che al + affianco alla domanda si sostituisse il – ?
E una sciocchezza giusto per trovare il pelo nell’uovo. Comunque veramente ottimo esempio.
P.S. Vi conosco da settembre e ho sempre cercato con i miei canali (blog compreso) di pubblicizzarvi. Siete davvero un ottima risorsa e a mio parere meritereste ancor più successo
Come non detto mi sa che avevo saltato l’ultimo pezzo
@yesWEBcan

Siamo una redazione di “pignoli”: non ci saremmo mai lasciati sfuggire un’occasione simile
Grazie per la pubblicità
Diamo veramente il massimo per questa comunità e i vostri pareri e/o critiche sono ciò che ci fa crescere. Il dialogo è il padre della conoscenza, quindi se pensate che questo esempio (o gli altri) si possa migliorare in qualche modo, discutiamone: alla fine il risultato resterà a noi
Ciao, innanzitutto complimenti veramente un tutorial ben fatto!
se volessi aprire un div e far chiudere in automatico quello aperto si potrebbe fare? Mi spiego meglio… nel tuo esempio se apro un div e poi ne apro un secondo rimangono aperti entrambi.
Volevo fare una domanda, dato che non ci sono riuscito da solo
Ho riletto di nuovo tutto (esempi e commenti compresi) ma non ho trovato nulla al riguardo.
Ciao fabio, benvenuto in YIW
È molto semplice ottenere l’effetto di cui parli: in pratica si tratta di nascondere gli altri elementi e poi mostrare quello che ci interessa. Possiamo riutilizzare il selettore che sfruttiamo per nascondere tutti gli elementi, ottenendo una cosa del genere:
...
//Nascondiamo tutti gli elementi, questa volta con slideUp
$("#faq li > *:not(h3)").slideUp("slow");
//mostriamo/nascondiamo le risposte
risposta.slideToggle("slow");
Qui puoi vedere un esempio.
Spero ti sia utile
Ciao e grazie!
Volevo realizzare da tempo una cosa del genere per un mio progetto (personale)!
E’ evidente che ancora devo capire molto di JQuery… quindi continuerò a seguire le tue lezioni sempre molto interessanti e pratiche
Grazie ancora.
Fabio
Ciao Fabio ti assicuro che con un po’ di impegno si possono raggiungere risultati di tutto rispetto, se già riesci a seguire questo codice sei a buon punto, continua così
Naturalmente, se vuoi, potrai mostrarci il tuo lavoro
Ciao, non mancherò di segnalare il mio portfolio/blog quando sarà ultimato
Ciao JustB, ho applicato l’effetto ad una lista che contiene degli articoli, l’idea è che cliccando sulla voce dell’articolo apparivano delle info aggiuntive cllegate all’articolo… ora ho notato che mettendo 2 span (o anche dei div) affiancati al 50% di larghezza (per dividere le info aggiuntive dell’articolo in 2 colonne affiancate) l’effetto di base rimane ma non si applica più il mio (quello che all’apertura di un div gli altri si chiudono e non rimangono aperti). Come mai? Eppure nel codice Jquery non noto nulla riferito a tag particolari…
Ciao Fabio, prova a mandarmi un link con un esempio, in modo che possa dare un’occhiata al codice
Ciao JustB, al momento non posso in quanto stò lavorando in locale… appena ho la possibilità pubblico un link
Buon anno!
Salve, lo script è molto efficace, presenta dei problemi sulle versioni di ie7 e ie8 alla chiusura si “attaccano i margini” dei div.
Ciao Daniele,
grazie per il riscontro.
Cercherò di pubblicare la versione aggiornata al più presto.