I deferred objects di jQuery hanno sancito una svolta nella storia della libreria. Per la prima volta viene applicato il concetto di queue e di stack non solo alle animazioni ma a qualsiasi blocco di codice avente una funzione propria.
In questo articolo, applicando questa tecnica agli slideshow di contenuti possiamo separarne due aspetti cruciali: l'azione di scorrimento e l'animazione su ciascuna slide.
Supponiamo di avere uno slideshow di contenuti in cui in ciascuna slide c'è un elemento nascosto (es. un div con classe desc
) che deve essere mostrato solo quando la slide corrente è in vista. Solitamente si usa un unico blocco di codice utilizzando la funzione di callback del metodo animate()
.
<div id="slideshow">
<div id="slideshow-wrapper">
<div class="slide">Slide 1<div class="desc">Descrizione</div></div>
<div class="slide">Slide 2<div class="desc">Descrizione</div></div>
<div class="slide">Slide 3<div class="desc">Descrizione</div></div>
</div>
</div>
Con i deferred objects possiamo separare le due azioni. Utilizzando un timer che incrementa un indice per accedere agli elementi del set tramite eq()
, possiamo usare i deferred objects tramite il loro metodo pipe()
, in questo modo:
var Slider = new function() {
var timer = null,
index = 0,
wrapper = $('#slideshow-wrapper'),
slides = $('div.slide', wrapper);
var slide = function() {
timer = setInterval(function() {
index++;
if(index == slides.length) {
index = 0;
$('div.desc', wrapper).hide();
}
$.Deferred(function(def) {
def.pipe(function() {
return wrapper.animate({
left: - slides.eq(index).position().left
}, 1000);
}).pipe(function() {
return slides.eq(index).find('div.desc').fadeIn(1000);
});
}).resolve();
}, 2000);
};
this.init = function() { slide(); };
}();
$(function() {
Slider.init();
});
All'interno di ciascuna funzione dei due metodi pipe() viene eseguita un'azione distinta e separata. Il metodo in questione dei deferred objects ha la caratteristica di eseguire le azioni in sequenza. Volendo avremmo potuto anche definire le azioni in due funzioni separate dal contesto corrente. Ad esempio:
var move = function(element, set, index) {
element.animate({
left: - set.eq(index).position().left
}, 1000);
};
Il punto è questo: suddividere logicamente i compiti in microporzioni di codice, ciascuna con un compito preciso. In questo modo il codice finale è molto più chiaro, e questo è utilissimo nel caso di effetti o animazioni complesse.
L'esempio finale e il codice completo è disponibile in allegato.