Un paio di mesi fa, per un mio caro amico web designer, ho sviluppato molto velocemente un paio di semplici funzioni javascript che permettono di gestire lo scorrimento di un div tramite lo slider di jQueryUI e la rotella del mouse.
Il funzionamento è abbastanza classico: si fa “scorrere” il div dei contenuti sotto un div “maschera” di dimensioni prefissate. Diciamo una versione rivisitata dei div con “overflow: auto;” e annessa scrollbar colorata del mai-glorioso internet explorer 6.0.
Le librerie che ho usato per realizzare lo slider sono jQuery, jQueryUI e il plugin mousewheel di Brandon Aaron, il tutto condito da un minimo di CSS, specie quello che riguarda la customizzazione dello slider. L’idea è quella di impostare l’offset superiore (la proprietà css “top”) massimo del div dei contenuti come valore massimo dello slider; così che muovendo lo slider in un range che va da 0 a X, cambi anche la proprietà top del div.
Vediamo ora l’implementazione dello slider e in seguito passeremo alla customizzazione.
<html> <head> <title>Slider verticale</title> <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css" type="text/css" media="all" /> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script> <script src="jquery.mousewheel.min.js" type="text/javascript"></script> <style> * { margin: 0px; padding: 0px; } .clear { clear:both; } #content { width:510px; margin:100px auto; } .news { border:1px solid #000000; margin-bottom: 10px; } #right { float:right; height:150px; width:50px; } #slider-vertical { height:150px; } #maschera { width:450px; height:150px; overflow:hidden; position:relative; } #contenuti { position:absolute; top:0px; left:0px; width:450px; } </style> </head> <body> <div id="content"> <div id="right"> <div id="slider-vertical"></div> </div> <div id="center"> <div id="maschera"> <div id="contenuti"> <div class="news">1 riga</div> <div class="news">2 righe<br />2 righe</div> <div class="news">3 righe<br />3 righe<br />3 righe</div> <div class="news">4 righe<br />4 righe<br />4 righe<br />4 righe</div> <div class="news">5 righe<br />5 righe<br />5 righe<br />5 righe<br />5 righe</div> </div> </div> </div> <div class="clear"></div> </div> <script type="text/javascript"> function scroll(max_height,value) { var val = -1*(max_height-value); $('#contenuti').css('top',val+'px'); } $(function() { max_height = parseInt($('#contenuti').css('height')) - parseInt($('#maschera').css('height')); $slider = $("#slider-vertical").slider({ orientation: "vertical", range: "min", min: 0, max: max_height, value: max_height, slide: function( event, ui ) { scroll(max_height,ui.value); } }); $('#contenuti').bind('mousewheel', function(event, delta) { scrollDelta = 20; var value = parseInt($slider.slider('value')); value += (delta > 0 ? scrollDelta : -scrollDelta) if (value > max_height) value = max_height; else if (value < 0) value = 0; $slider.slider('value', value); scroll(max_height,value); return false; }); }); </script> </body> </html>
Per realizzare l’esempio, abbiamo usato un minimo di css per dare forma alla pagina (la parte in alto) e per creare la nostra maschera e posizionare lo slider. I valori che vorrete sicuramente cambiare sono la larghezza e l’altezza minima della maschera e dei contenuti (#maschera, #contenuti) così come l’altezza dello slider e della sua colonna che lo contiene (#slider-vertical, #right).
* { margin: 0px; padding: 0px; } .clear { clear:both; } #content { width:510px; margin:100px auto; } .news { border:1px solid #000000; margin-bottom: 10px; } #right { float:right; height:150px; width:50px; } #slider-vertical { height:150px; } #maschera { width:450px; height:150px; overflow:hidden; position:relative; } #contenuti { position:absolute; top:0px; left:0px; width:450px; }
Il javascript che abbiamo utilizzato è abbastanza semplice ed è riportato di seguito
function scroll(max_height,value) { var val = -1*(max_height-value); $('#contenuti').css('top',val+'px'); } $(function() { max_height = parseInt($('#contenuti').css('height')) - parseInt($('#maschera').css('height')); $slider = $("#slider-vertical").slider({ orientation: "vertical", range: "min", min: 0, max: max_height, value: max_height, slide: function( event, ui ) { scroll(max_height,ui.value); } }); $('#contenuti').bind('mousewheel', function(event, delta) { scrollDelta = 20; var value = parseInt($slider.slider('value')); value += (delta > 0 ? scrollDelta : -scrollDelta) if (value > max_height) value = max_height; else if (value < 0) value = 0; $slider.slider('value', value); scroll(max_height,value) }); });
Possiamo vedere come la funzione “scroll” (riga 40) sia quella che si occupa di cambiare l’offset superiore del div (proprietà “top” del css) che, grazie al posizionamento assoluto, risulterà scorrere sotto alla maschera (posizionata in modo relativo).
Dopo la funzione “scroll” c’è il codice che viene eseguito solo al document ready (riga 48) e consistono nell’instanzazione dello slider jQueryUI con valore massimo pari alla differenza tra l’altezza effettiva del div dei contenuti e quella del div maschera (riga 46). Per questioni di praticitià, la differenza chiamata “max_height” viene calcolata in una variabile esterna alle funzioni dentro il document ready, ma vi sprono a fare di meglio!
Nel metodo slide dello slider viene chiamata la funzione “scroll” passando l’altezza massima calcolata e l’attuale valore assunto dallo slider.
Subito dopo c’è la parte che riguarda la rotella del mouse (riga 59). All’interno della funzione anonima collegata all’evento mousewheel troviamo un parametro per regolare di quanti pixel vogliamo far scorrere il div (scrollDelta), un controllo per capire la direzione dello scroll più un check del valore massimo o minimo risultante in seguito all’azione. Il nuovo valore di offset così ottenuto viene quindi assegnato allo slider e in seguito passato alla funzione “scroll” (righe 65-66).
Ora che abbiamo visto il funzionamento, passiamo alla customizzazione grafica! Nell’esempio allegato ho messo un pomodoro come indicatore dello slider e poi ho cambiato lo sfondo e il bordo dello slider. Niente di complesso, giusto per rendere l’idea.
Vi riporto di seguito solo l’aggiunta di css che ho fatto allo script.
/* customizzazione */ #slider-vertical { background: #FF0000; border:1px dotted #FFFFFF; } #slider-vertical > div { background: #FFFFFF; border: 0; margin: 0 auto; } #slider-vertical > a { background: url(pomodoro.png) no-repeat center center; border: 0; height:24px; width:24px; } /* fine customizzazione */
Update: per venire incontro alle esigenze di molti (Niko :P), allego una versione “migliorata” che consente di gestire più slider nella stessa pagina.