Slider Nivo con Mootools ed ereditarietà oggetti

Per continuare il nostro cammino con la OOP, ho deciso di mostrarvi un esempio pratico e di facile comprensione dell’ereditarietà delle classi. In questo intervento riprenderò lo slider Nivo precedentemente realizzato da me utilizzando come framework Mootools e sfruttando le classi per definire due tipologie di slider, una (padre) con sistema di navigazione a frecce e un’altra (figlia) che implementerà anche una navigazione a pallini, sfruttando metodi e proprietà definite nella classe padre.

Consiglio, per chi se lo fosse perso, di riguardare l’introduzione alla Object Oriented Programming, di cui ho parlato nel post precedente, prima di proseguire alla lettura di questo intervento.

Markup HTML e regole Css

La struttura HTML e le regole Css che ho utilizzato per questo esempio sono identiche a quelle presenti nel post sullo Slider Nivo che si può trovare a questo link. L’unica differenza sarà l’aggiunta di una regola css display:block al primo elemento della lista.

Codice Javascript/Mootools

Analizziamo passo dopo passo la definizione dei metodi e delle classi da me realizzate in questo post. Per la realizzazione dello slider ho utilizzato due classi. La prima, Nivo, sarà la classe padre, che incorporerà metodi e proprietà per creare uno slideshow di tipo Nivo con sistema di navigazione a frecce, la seconda Navigation, aggiungerà alla navigazione a frecce anche dei pallini cliccabili.

Per prima cosa definiremo una proprietà che ci servirà molto spesso all’interno dei metodi successivi, che non sarà altro che una sorta di puntatore all’elemento attuale dello slider. Essa ci permetterà anche di ricavare l’elemento successivo della lista di slide.

[code type=”javascript”]counter: 0[/code]

Il primo metodo che definiremo servirà per inizializzare il nostro oggetto e quindi i parametri in ingresso che ci serviranno all’interno dei metodi successivi.

[code type=”javascript”]
initialize: function ( slider, next, prev) {

this.slider = slider;

this.next = next;

this.prev = prev;

this.elements = this.slider.getElements(‘.element’);

this.nEle = this.elements.length;

}
[/code]

slider sarà l’elemento padre delle slide figlie, next la freccia a destra dello slideshow, prev la freccia a sinistra dello slideshow, elements sarà un array contenente tutti gli elementi dello slider e nEle il numero di elementi.

I prossimi due metodi verranno utilizzati per definire l’animazione di fadeOut() e fadeIn() delle nostre slide. Per farlo ci serviremo della classe Fx di Mootools che con i suoi metodi .reveal() e .dissolve() ci permetterà di creare un’animazione sulla opacità dei nostri elementi.

[code type=”javascript”]
fadeOut: function(element) {

element.dissolve();

},

fadeIn: function(element) {

element.reveal();

}
[/code]

Il prossimo metodo, getElementPosition(), ci permetterà di ricavare l’elemento successivo o precedente della lista a seconda del parametro direction che gli diamo in ingresso, che potrà essere ‘+’ o ‘-’.

[code type=”javascript”]
getElementPosition: function(direction) {

if ( direction == ‘+’) {

if ( this.counter == this.nEle-1) {

this.counter = 0;

} else {

this.counter++;

};

} else if ( direction == ‘-‘) {

if ( this.counter == 0 ) {

this.counter = this.nEle-1;

} else {

this.counter–;

}

};

nextSlide = this.elements[ this.counter ];

return nextSlide;

}
[/code]

Se il parametro direction avrà valore ‘+’, e il valore di counter non sarà uguale al numero di elementi, la proprietà counter verrà incrementata di 1, altrimenti counter verrà riportata a 0 poiché significherà che la posizione attuale sarà esattamente sull’ultimo elemento, e quindi bisognerà riportarsi all’inizio della lista.

Se il parametro direction avrà valore ‘-’, e il valore di counter non sarà uguale a 0 (primo elemento), counter verrà decrementato di 1. Nel caso di counter = a 0 ci si sposterà in fondo alla lista.

Al termine di questi controlli ci salveremo l’elemento n-esimo cercandolo nel nostro array elements. Passo finale un semplice return del nostro elemento successivo.

I prossimi metodi, nextElement() e prevElement(), ci serviranno per effettuare la vera e propria funzione di slide tra gli elementi della lista. Prendiamo in considerazione nextElement():

[code type=”javascript”]
nextElement: function() {

this.next.addEvent(‘click’, function() {

this.fadeOut(this.elements[this.counter]);

nextSlide = this.getElementPosition(‘+’);

this.fadeIn(nextSlide);

}.bind(this));

},

prevElement: function() {

this.prev.addEvent(‘click’, function() {

this.fadeOut(this.elements[this.counter]);

nextSlide = this.getElementPosition(‘-‘);

this.fadeIn(nextSlide);

}.bind(this));

}
[/code]

Assegneremo alla freccia next, precendemente passata come parametro nella inizializzazione del nostro oggetto, un evento click. Questo evento svolgerà 3 semplici passi. Per prima cosa richiamerà il metodo fadeOut() sull’elemento attuale, dopodiché andrà a ricavare il prossimo elemento con getElementPosition() e infine invocherà il fadeIn() dell’elemento successivo. Ho utilizzato .bind(this) per passare il contesto della classe all’interno del metodo per poter risalire alle nostre proprietà e metodi precedentemente definite.

prevElement() differirà da nextElement() per due fattori: l’evento click verrà invocato sulla freccia prev e il getElementPosition() sarà richiamato per estrarre l’elemento precedente, passandogli come parametro il valore ‘-’.

L’ultimo metodo di questa classe è play() che istanzia i listener per gli eventi sulle frecce.

[code type=”javascript”]
play: function() {

this.nextElement();

this.prevElement();

}
[/code]

A questo punto se noi provassimo ad instanziare un oggetto di questa classe Nivo, avremmo una navigazione con slideshow Nivo perfettamente funzionante. Per esempio:

[code type=”javascript”]
var nivo = new Nivo( document.getElement(‘.nivo’), document.getElement(‘.next’), document.getElement(‘.prev’));

nivo.play();
[/code]

Ora definiamo una classe figlia Navigator che estenderà la classe padre Nivo e che al suo interno utilizzerà alcuni metodi e proprietà già definiti, ridefinirà altri metodi in base alle sue esigenze e ne definirà di nuovi per svolgere nuove funzionalità. Ecco la dichiarazione:

[code type=”javascript”]
var Navigator = new Class({

Extends: Nivo,

navi: {},

circles: [],
[/code]

I metodi initialize(), fadeOut(), fadeIn() e getElementPosition() verranno ereditati senza alcuna modifica da parte della classe Navigator.

Ora, invece, redifiniremo il metodo nextElement e prevElement aggiungendo una piccola modifica al codice:

[code type=”javascript”]
nextElement: function() {

this.next.addEvent(‘click’, function( event ) {

this.fadeOut(this.elements[this.counter]);

this.circles[ this.counter ].removeClass(‘active’);

nextSlide = this.getElementPosition(‘+’);

this.fadeIn(nextSlide);

this.circles[ this.counter ].addClass(‘active’);

}.bind(this));

},

prevElement: function() {

this.prev.addEvent(‘click’, function( event ) {

this.fadeOut(this.elements[this.counter]);

this.circles[ this.counter ].removeClass(‘active’);

nextSlide = this.getElementPosition(‘-‘);

this.fadeIn(nextSlide);

this.circles[ this.counter ].addClass(‘active’);

}.bind(this));

}
[/code]

Sostanzialmente in entrambi i casi andremo a spostare la classe active dal pallino attuale a quello successivo alla transizione di slide.

Ora andiamo a definire il metodo che ci servirà per creare i pallini di navigazione in base al numero di slide che abbiamo nella nostra lista.

[code type=”javascript”]
createCircles: function() {

this.navi = new Element(‘div’, {

‘class’: ‘navi’

});

this.navi.inject(document.getElement(‘.nivo-slider’));

i = 0;

for ( i = 0; i < this.nEle; i++ ) { var opts = { href: 'javascript:void(0)', rel: i }; if ( i == 0 ) { opts['class'] = 'active'; } var circle = new Element('a', opts); circle.inject(this.navi); this.circles.push(circle); }; } [/code] Innanzitutto inseriremo un div contenente i pallini, creandolo con Element() di Mootools. Eseguiremo un semplice for per ogni elemento presente nella lista, e per ognuno di questi andremo a inserire con una .inject() un elemento a html sempre utilizzando Element() di Mootools, alla quale passeremo una variabile contenente le opzioni che ci serviranno, ovvero l’attributo href ‘javascript:void(0)’ e un attributo rel incrementante che verrà utilizzato per ricavare la posizione dell’elemento slide al momento del click su uno dei pallini. Assegneremo al primo pallino la classe active e come ultima operazione, creeremo un array contenente tutti i pallini tramite una operazione di .push(). Definiamo ora il metodo nextCircle(). Questo metodo sarà colui che ci permetterà di eseguire una transizione di slide dall’elemento attuale all’elemento target sul quale abbiamo cliccato. [code type="javascript"] nextCircle: function() { document.getElements('.navi a').addEvent('click', function( event ) { this.fadeOut(this.elements[this.counter]); this.circles[ this.counter ].removeClass('active'); this.counter = parseInt(event.target.rel) ; this.fadeIn(this.elements[this.counter]); this.circles[ this.counter ].addClass('active'); }.bind(this)); } [/code] Il metodo è molto simile a nextElement e prevElement precedentemente definiti. La differenza è che in questo metodo non verrà richiamato getElementPosition ma utilizzeremo l’attributo rel del pallino cliccato per andare a ricavarci la posizione della slide successiva. Per far ciò faremo un parseInt() del valore di rel e lo assegneremo a this.counter. All’interno di questo metodo, inoltre, gestiremo anche lo spostamento della classe active dal pallino precedente a quello successivo. Ultima redifinizione sarà quella del metodo play(), al quale applicheremo l’inizializzazione di altri due metodi. [code type="javascript"] play: function() { this.createCircles(); this.nextElement(); this.prevElement(); this.nextCircle(); } [/code] Passo finale, l’instanza della classe e il richiamo del metodo play() [code type="javascript"] var navigator = new Navigator( document.getElement('.nivo'), document.getElement('.next'), document.getElement('.prev')); navigator.play(); [/code] A questo link, come sempre, la possibilità di visualizzare una demo creata da me su jsfiddle.

Condividi