Uno slideshow composito in jQuery è uno slideshow al cui interno ciascuna slide presenta ulteriori animazioni oltre all'animazione principale dello scorrimento. Per ottenere tale effetto ricorreremo al metodo animate()
e alla sua funzione di callback che ci permette di concatenare più animazioni insieme. Useremo un oggetto chiamato Slider
che avrà un unico metodo pubblico per gestire tali effetti. È di fondamentale importanza che tale oggetto disponga anche di un metodo privato per ottenere gli offset delle slide e poter così creare l'effetto principale di scorrimento. Gli effetti secondari si limitano a modificare la larghezza di due elementi posizionati in modo assoluto all'interno di ciascuna slide.
Partiamo dalla nostra marcatura:
<div id="slideshow">
<div id="slideshow-wrapper">
<div class="slide s1">
<div class="text-left">Lorem ipsum dolor</div>
<div class="text-right">et ideo autem aquis</div>
</div>
<div class="slide s2">
<div class="text-left">Ibam forte via sacra</div>
<div class="text-right">nescio quid meditans nugarum</div>
</div>
<div class="slide s3">
<div class="text-left">Quia fluxa est et lubrica</div>
<div class="text-right">et ad similitudinem aquae</div>
</div>
</div>
</div>
<div id="slideshow-controls">
<a href="#" id="prev"><</a>
<a href="#" id="next">></a>
</div>
Il nostro CSS non presenta particolari problematiche:
#slideshow {
margin: 0 auto;
width: 700px;
height: 500px;
position: relative;
overflow: hidden;
}
#slideshow-wrapper {
width: 2100px;
height: 500px;
position: relative;
}
div.slide {
width: 700px;
height: 500px;
float: left;
position: relative;
line-height: 500px;
text-align: center;
font-size: 2em;
color: #fff;
}
div.s1 {
background: #d40;
}
div.s2 {
background: #f60;
}
div.s3 {
background: #c60;
}
div.text-left {
width: 0px;
height: 250px;
position: absolute;
top: 0;
left: 0;
line-height: 250px;
text-align: center;
background: #800;
font-size: 1em;
overflow: hidden;
}
div.text-right {
width: 0px;
height: 250px;
position: absolute;
bottom: 0;
right: 0;
line-height: 250px;
text-align: center;
background: #c00;
font-size: 1em;
overflow: hidden;
}
#slideshow-controls {
width: 700px;
margin: 0 auto;
padding: 1em 0;
text-align: center;
}
#slideshow-controls a {
background: #a40;
color: #fff;
padding: 0.3em 0.6em;
font-size: 2em;
text-decoration: none;
margin-right: 0.5em;
}
I due elementi all'interno di ciascuna slide hanno una larghezza pari a zero, perchè ciò che vogliamo ottenere è un effetto di espansione. Per far ciò abbiamo anche usato il posizionamento per creare l'effetto di un'espansione da sinistra a destra e da destra verso sinistra.
Ora dobbiamo creare il nostro oggetto. Prima definiamo i membri privati di tale oggetto:
var Slider = new function() {
var wrapper = $('#slideshow-wrapper', '#slideshow');
var slides = $('div.slide', wrapper);
var len = slides.length;
var index = 0;
var prevBtn = $('#prev', '#slideshow-controls');
var nextBtn = $('#next', '#slideshow-controls');
var getSlidePositions = function() {
var positions = [];
$('div.slide', '#slideshow-wrapper').each(function(i) {
var left = $(this).position().left;
positions[i] = left;
});
return positions;
};
// continua
}();
Il metodo privato che abbiamo definito compie un loop tra le slide e popola un array con gli offset di tali slide. Questi offset serviranno per l'effetto di scorrimento. A questo punto dobbiamo creare il nostro metodo pubblico che chiameremo slide()
. Questo metodo associa un evento click
ai due bottoni di navigazione, compiendo le seguenti operazioni:
- In avanzamento, il contatore
index
viene incrementato. In rewind, viene decrementato. - Si fa in modo che il contatore non abbia mai un valore superiore al numero di slide o inferiore a 0.
- Se gli elementi delle slide sono già stati espansi, li si riporta al loro stato iniziale.
- Viene fatto scorrere il contenitore principale usando il contatore come indice per l'array di offset.
- Viene selezionata la slide corrente usando il contatore con il metodo
eq()
. - Vengono fatti espandere i due elementi all'interno della slide corrente, in sequenza.
Ecco il codice:
// continua
this.slide = function() {
var offsets = getSlidePositions();
prevBtn.click(function(event) {
$('div.text-left').css('width', 0);
$('div.text-right').css('width', 0);
index--;
if(index == -1) {
index = 0;
}
var slide = slides.eq(index);
var textLeft = slide.find('div.text-left');
var textRight = slide.find('div.text-right');
wrapper.animate({
left: - offsets[index]
}, 'slow', function() {
textLeft.animate({
width: 700
}, 'slow', function() {
textRight.animate({
width: 700
}, 'slow');
});
});
event.preventDefault();
});
nextBtn.click(function(event) {
$('div.text-left').css('width', 0);
$('div.text-right').css('width', 0);
index++;
if(index == len) {
index = 0;
}
var slide = slides.eq(index);
var textLeft = slide.find('div.text-left');
var textRight = slide.find('div.text-right');
wrapper.animate({
left: - offsets[index]
}, 'slow', function() {
textLeft.animate({
width: 700
}, 'slow', function() {
textRight.animate({
width: 700
}, 'slow');
});
});
event.preventDefault();
});
};
Potete visionare l'esempio finale in questa pagina.