Per OOP, acronimo di Object Oriented Programming, si intende un metodo di programmazione che si differenzia dalla normale programmazione procedurale. Nell’OOP è possibile appunto definire delle classi che poi verranno istanziate da elementi chiamati oggetti.
In questo intervento, mi occuperò di riprendere lo slider da me precedentemente realizzato con jQuery e di ricreare la stessa situazione utilizzando il framework Mootools, che ci dà la possibilità di utilizzare la programmazione ad oggetti.
Introduzione alla programmazione ad oggetti
Per chi ancora non ha ben chiaro come funzioni l’OOP, vi spiegherò in breve come funziona e quali vantaggi fornisce.
Sono 3 i punti fondamentali della programmazione ad oggetti:
- Incapsulamento
- Ereditarietà
- Polimorfismo
Per incapsulamento si intende la possibilità di definire dati, quindi proprietà e metodi, all’interno dell’oggetto che però possano essere utilizzati soltanto dall’oggetto stesso. In questo modo diamo la possibilità di proteggere i dati interni dell’oggetto, e quindi di poter invocare metodi dell’oggetto senza poter vedere effettivamente che codice esegue il suddetto metodo.
L’ereditarietà è la possibilità di creare delle classi che ereditano metodi e procedure di un’altra classe che è detta anche superclasse.A queste sottoclassi è possibile assegnare ulteriori metodi e procedure o addirittura ridefinire i metodi della superclasse. Ad esempio possiamo ereditare due metodi dalla superclasse, ridefinirne uno e aggiungerne altri.
Il polimorfismo è la proprietà che ci permette di invocare un metodo definito sia nella superclasse che in n sottoclassi in modo distinto, a seconda dell’oggetto che andiamo a istanziare. Per esempio se abbiamo un metodo definito in una superclasse che poi successivamente viene ridefinito in una o più sottoclassi, possiamo istanziare più oggetti contemporaneamente con classi differenti. Ognuno di questi oggetti richiamerà il metodo definito dalla propria classe.
Markup HTML e regole Css
Per questo esempio il markup HTML e le regole CSS definite sono identiche a quelle dell’esempio precedentemente realizzato presente a questo link. L’unica differenza è che, avendo calcolato la larghezza del singolo elemento dello slider in un modo differente, ho aggiunto un tag div class=”thumbs-content” che, impostato con larghezza fissa, altezza fissa, e overflow nascosto, mi servirà per nascondere una porzione di contenuto del div id=”thumbs”.
Codice Javascript/Mootools
Veniamo finalmente al fulcro della creazione dello slider OOP. Sostanzialmente ho definito una classe con al suo interno proprietà e metodi che mi permetteranno di far muovere gli elementi al click sulle frecce. Tutto ciò sarà possibile istanziando l’oggetto con i parametri corretti, e invocando il metodo .play();. Sarà possibile, inoltre, impostare a piacimento la velocità di transizione di movimento. Iniziamo a vedere come si dichiara una classe in modo generico:
[code type=”javascript”]
var Slider = new Class({
proprieta1: proprieta1,
proprieta2: proprieta2,
metodo1: function() {
// istruzioni
},
metodo2: function() {
//istruzioni
}
});
[/code]
In questo modo definiamo proprietà, quelle che comunemente vengono intese come variabili e metodi quelle che di solito si usa chiamare funzioni. Nello specifico ho definito queste proprietà e diversi metodi che man mano vi illustrerò:
[code type=”javascript”]
width: 0,
start: 0
[/code]
Per prima cosa definiamo il metodo che prenderà i parametri che noi passiamo al momento dell’istanza del nostro oggetto e che ci serviranno nel corso dello script tramite il costruttore della classe: il metodo initialize.
[code type=”javascript”]
initialize: function( slider, arrowDx, arrowSx, nEle, speed ) {
this.slider = slider;
this.arrowDx = arrowDx;
this.arrowSx = arrowSx;
this.nEle = nEle;
this.speed = speed;
this.thumbs = this.slider.getElementById(‘thumbs-wrapper’);
}
[/code]
Passeremo rispettivamente: lo slider, la freccia destra, la freccia sinistra, il numero di elementi e come parametro facoltativo la velocità espressa in millisecondi. La proprietà thumbs verrà ricavato da this.slider.
Il metodo successivo, getWidth, ricaverà la larghezza del singolo elemento attraverso la larghezza dello slider divisa per 3 (numero di elementi che si visualizzano del nostro slider).
[code type=”javascript”]
getWidth: function() {
var size = this.slider.getSize();
return size.x / 3 ;
}
[/code]
getStart ci servirà per ottenere il punto di partenza da cui dovrà partire la proprietà css left del nostro div id=”thumbs-wrapper”. Si ricava il valore moltiplicando la larghezza passata come parametro per il numero di elementi.
[code type=”javascript”]
getStart: function() {
this.start = -this.width * this.nEle;
this.thumbs.setStyle(“left”, this.start + “px”);
}
[/code]
Il prossimo metodo verrà utilizzato per ottenere la posizione attuale e quindi il valore “left” durante ogni ciclo di slide con la seguente funzione:
[code type=”javascript”]
getCurrentPos: function() {
return parseInt(this.thumbs.getStyle(“left”));
}
[/code]
Quest’ultimo verrà richiamato all’interno delle operazioni di slide.
Passiamo ora ad un metodo un po’ più interessante, che ci permetterà di inserire una lista di elementi clonati in fondo e a all’inizio dei nostri elementi, questo per poter ottenere un ciclo infinito una volta che arriviamo alla fine della lista o torniamo al primo elemento a ritroso.
[code type=”javascript”]
cloneElements: function() {
var elements = $$(‘#thumbs-wrapper .thumb’);
var first = elements[0];
elements.each(function(element) {
element.clone()
.addClass(‘cloned’)
.inject( this.thumbs )
.clone()
.inject( first, ‘before’ );
}.bind(this));
}
[/code]
Per prima cosa otteniamo un array, elements, contenente tutti i nostri elementi dello slider. Dopodiché ricaviamo il primo elemento della lista e infine eseguiamo in ciclo per ogni elements con la funzione .each(). Dentro questo .each() utilizzeremo la funzione di mootools .inject(), che inserirà i nostri elementi clonati con la funzione .clone() in coda al div id=”thumbs-wrapper” con .inject( this.thumbs) e all’inizio con .inject( first, ‘before’);.
I prossimi due metodi serviranno per effettuare il movimento di slide. Analizziamo passo dopo passo come funzionano:
[code type=”javascript”]
slideRight: function() {
if (!this.speed) { this.speed = 500 };
slideRight = new Fx.Morph(this.thumbs, {
duration: this.speed,
transition: Fx.Transitions.Sine.easeOut,
onComplete: function() {
if ( ( this.getCurrentPos() ) == 2 * this.start ) {
this.thumbs.setStyle(“left”, this.start + “px”);
}
}.bind(this),
});
[/code]
La prima istruzione controllerà se la proprietà speed è stata valorizzata (quando viene istanziato l’oggetto), altrimenti imposterà un valore di default. Dopodiché con l’utilizzo della classe di mootools Fx.Morph definiamo come funzionerà l’animazione del nostro slider. Impostiamo la durata della transizione dello sliding con il parametro duration, con transition definiamo il tipo di transizione e infine al complete della transizione (onComplete) andiamo a riportare lo slider in posizione iniziale se ci siamo posizionati sull’ultimo elemento, in modo tale da poter ottenere un loop infinito. Una nota molto importante è l’utilizzo della funzione .bind(this). Essa mi permette, sostanzialmente, di passare il contesto desiderato, nel nostro caso quello della classe, ad un metodo o ad una funzione definita e quindi di poter utilizzare this.thumbs all’interno della funzione richiamata al complete. Se non avessi effettuato il bind in questa funzione, non avrei potuto utilizzare la proprietà this.thumbs al suo interno.
Passo successivo è la definizione del listener per l’evento di click sulla freccia:
[code type=”javascript”]
this.arrowDx.addEvent(‘click’, function() {
var currentPos = this.getCurrentPos(),
left = currentPos – this.width;
slideRight.start({
‘left’: [ currentPos, left]
});
}.bind(this));
[/code]
All’evento click sulla freccia che abbiamo passato come proprietà al momento dell’istanza dell’oggetto, applicheremo uno slide che partirà dalla posizione attuale e arriverà alla posizione successiva. La posizione attuale la ricaviamo con il metodo precedentemente definito, ossia getCurrentPos(), e lo spostamento sarà dato dalla posizione attuale + la larghezza di un elemento.
Il metodo della freccia di sinistra sarà praticamente identico a differenza dello spostamento che sarà verso sinistra e che al complete della funzione controlleremo quanto la posizione attuale avrà raggiunto il primo elemento della lista.
[code type=”javascript”]
slideLeft: function() {
if (!this.speed) { this.speed = 500 };
slideLeft = new Fx.Morph(this.thumbs, {
duration: this.speed,
transition: Fx.Transitions.Sine.easeOut,
onComplete: function() {
if ( ( this.getCurrentPos() ) == 0 ) {
this.thumbs.setStyle(“left”, this.start + “px”);
}
}.bind(this),
});
this.arrowSx.addEvent(‘click’, function() {
var currentPos = this.getCurrentPos(),
left = currentPos + this.width;
slideLeft.start({
‘left’: [ currentPos, left]
});
}.bind(this));
[/code]
A questo punto rimane soltanto da definire un metodo che richiamerà tutti i metodi precedentemente definiti:
[code type=”javascript”]
play: function() {
this.width = this.getWidth();
this.getStart();
this.cloneElements();
this.slideRight();
this.slideLeft();
}
[/code]
Istanziamo l’oggetto e “schiacciamo” play!
[code type=”javascript”]
var slider = new Slider( $(‘thumbs’), $$(‘a.dx-arrow’), $$(‘a.sx-arrow’), 5, 1000 );
slider.play();
[/code]
Lascio a questo link la possibilità di visualizzare e testare una demo creata da me.