multicolumn lists con jQuery
March 12th, 2007Problema:
Creare una lista disposta su 3 colonne, senza sapere a priori quanto è lunga la lista.
E aggiungono:
Non preoccuparti di quanto è lunga la lista, ci servono 3 colonne di links. La lista andrà su un sito pubblico.
mmmh. vediamo…
L’obiettivo, come al solito, è scrivere il meno possibile. Ma non perchè sono lazy, ma perchè è una sfida. Quindi mi serve certamente 3 colonne UL. Flottate, così ottengo 3 colonne. ok.
Ma per scrivere meno, dovrei avere una sola lista….
Per creare una lista su tre colonne, se sapessi quanti elementi sono nella prima e nella seconda colonna non sarebbe difficile. Basta applicare al primo LI della mia ipotetica seconda colonna, un margin-top negativo pari all’altezza della prima, ed un margin-left sempre pari alla larghezza delle colonne (tutte e due le precedenti, e così via).
<ul id="mainlist"><li class="licol1"><a href="#">1 Exxon Mobil (XOM)</a></li>
<li class="licol1"><a href="#">2 Exxon Mobil (XOM)</a></li>
<li class="licol1"><a href="#">3 Exxon Mobil (XOM)</a></li>
<li class="licol1"><a href="#">n --- --- </a></li>
<li class="licol2"><a href="#">1 Exxon Mobil (XOM)</a></li>
<li class="licol2"><a href="#">2 Exxon Mobil (XOM)</a></li>
<li class="licol2"><a href="#">n --- --- </a></li>
<li class="licol3"><a href="#">1 Exxon Mobil (XOM)</a></li>
<li class="licol3"><a href="#">2 Exxon Mobil (XOM)</a></li>
<li class="licol3"><a href="#">n --- --- </a></li>
</ul>
Ma se questa lista non so quanto è lunga? Voglio dire, se mi possono anche dividere in tre le liste, assegnare una classe diversa per ogni blocco di lista, come posso inserire il margine negativo al punto prestabilito per fare andr sù la seconda e la terza colonna? E quale è questa misura, esattamanete in pixel?(E’ evidente che questa lista viene creata dinamicamente tramite qualcosa server-side come per es. una JSP.)
Ecco che mi viene incontro jQuery una libreria javascript ideata da John Resig e attualmente molto, molto diffusa ed estesa da molteplici plugins sviluppati dalla community.
Infatti il motto di jQuery è “write less, do more” e significa che jQuery serve per scrivere meno javascript ed ottenere di più. Tra le cose che sin dall’inizio mi hanno impressionato positivamente di questa libreria, oltre ai metodi built-in per quel che riguarda Ajax, qualche effetto e in generale la manipolazione del DOM, sono i selettori (supporta la sintassi di CSS 1-3
e basic XPath ).
E vediamo con questi selettori cosa si può fare. Ecco il codice che mi risolve brillantemente il problema delle tre liste parametriche affiancate, e del loro posizionamento.
$(document).ready(function(){
elNumberInColOne = $(".licol1").length;
var PixelCountColOne = 0;
for (i=0; i<elNumberInColOne ; i++){
PixelCountColOne += $("li.licol1:eq("+i+")").height() + 9;
}
$("ul#mainlist > li.licol2:eq(0)").css({ marginTop: - PixelCountColOne});
ElNumberInColTwo = $(".licol2").length;
var PixelCountColTwo = 0;
for (i=0; i<ElNumberInColTwo ; i++){
PixelCountColTwo += $("li.licol2:eq("+i+")").height() + 9;
}
$("ul#mainlist > li.licol3:eq(0)").css({ marginTop: -PixelCountColTwo});
});
La parte più interessante, secondo me qui da notare è il selettore inserito nel ciclo "li.licol1:eq("+i+")").height() + 9 che cerca nel LI con classe “licol1″ OGNI elemento LI e ne calcola l’altezza in px. +9 poi sono il padding top e bottom e il bordo assegnati via CSS al singolo LI (al suo A, a dire il vero).
Quindi cosa fa questo script?
- Prende la prima colonna, e per ogni LI ne calcola l’altezza in pixel
- Assegna al primo LI della seconda colonna
"ul#mainlist > li.licol2:eq(0)"un margin-top negativo pari all’altezza della prima colonna. Il margin-left resta assegnato dal css. - Ripete lo step 2 nella terza colonna
Et voilà. Css multicolumn lists.
Comunque allego il sorgente dell’esempio, per chi volesse usarlo.
