Effetto assolvenza, dissolvenza automatica con Mootools

moofxSpesso mi piace lanciare dei piccoli messaggi di notifica per evidenziare all”utente che qualcosa è successo nella pagina. Ad esempio dopo aver schiacciato un bottone su di un form per confermare l”avvenuto salvataggio via AJAX, oppure far apparire un throbber ecc.

La cosa più semplice è far apparire messaggio vicino a dove l”occhio dell”utente sta già gironzolando così da lanciare un feedback immediato.

Da designer, non mi piacciono le cose troppo complicate perciò voglio trovare un modo semplice per dare un effetto moderno (leggi animazione) alla funzionalità.

Quello che ho intenzione di fare è, tramite una chiamata javascript, far apparire in assolvenza il messaggio, fare in modo che questo se ne stia li per un po” e poi se ne vada da solo. Il tutto nel modo più semplice possibile.

Cominciamo a creare il nostro bottone con il messaggio:

Salva
Hai salvato con successo

Questa è la situazione dove tutti gli elementi che dobbiamo inserire sono visibili, mi permette di organizzare gli stile CSS senza dover ancora attivare la funzionalità (vedi la demo per il CSS finale).

Da notare che il messaggio rimane da parte al tasto “Salva”, lo faccio notare perchè la notifica deve stare preferibilemente dove l”utente ha già concentrato la sua attenzione: se il tasto salva è in fondo alla pagina, vi prego, non facciamo comparire un messaggio in cima alla pagina!! Purtroppo non è così scontato.

Ora nascondiamo il messaggio, dando di default questo stile allo span:

#message {
 opacity:0;
}

Test del codice

Cominciamo con il codice Javascript utilizzando, ovviamente ;), Mootools, esclusivamente
la libreria base:

[iframe src=”//mootools.net/shell/X43NY/30/embedded/”]

Analisi del codice

Per prima cosa assegno il mio codice al click del mouse sul link ed evito che questo mi porti all”indirizzo presente nel suo parametro href:

$("trigger").addEvent("click", function(e) {
 e.preventDefault();
 // ...
});

Ora voglio animare in assolvenza il bottone, lo faccio tramite un”istanza della classe FX.Morph creata direttamente dall”elemento che voglio animare (per approfondire si horoscope for sagittarius may seem unpredictable and able to get mad over a trifle, but the thing is that they are used to hide their emotions and weaknesses even from their beloved people, and they only let their feelings go when it’s too late to correct mistakes. legga l”articolo su Clientcide). Allo stesso modo avrei potuto usare Fx.Tween, ma Fx.Morph mi da la possibilità di animare altre proprietà CSS contemporaneamente. Notare quel setStyle() usato prima del morph: serve a resettare gli stili altrimenti alla prima esecuzione l”animazione verrà saltata.

 var target = $("message");
 target.setStyles({"opacity" : 0, "visibility" : "hidden"}); 

 var morph = target .get("morph");
 morph.start({"opacity" : 1})

E fin qui, al click l”oggetto appare. Ora però voglio che in automatico dopo un determinato tempo, esso scompaia.

Una catena di funzioni

Come tante classi di Mootools, anche Fx.Morph estende una serie di classi base tra cui la classe Chain su cui posiamo l”attenzione. Chain permette di concatenare una lista di funzioni (uno stack) che verranno eseguite una dopo l”altra, ognuna al termine di quella precedente.

Come si fa? Semplice, si definisce tramite il metodo chain() la lista di funzioni da lanciare, e successivamente si chiama il metodo callChain() che esegue la prima funzione utile della lista. Al termine dalla funzione lo stack viene accorciato di un elemento. Chiamando di nuovo callChain() si esegue la funzione successiva.

Si da il caso che Fx.Morph, al termine di ogni animazione, chiami in automatico la funzione callChain(), perciò ecco chiarita l”ultima parte di codice:

morph.start({"opacity" : 1}).chain(
 function() { this.callChain.delay(1000, this) },
 function() { this.start({ "opacity": 0 }); }
);

L”animazione viene lanciata tramite start(). Al termine lancia la prima funzione dello stack, la quale aspetta 1 secondo prima di lanciare manualmente callChain() che a sua volta lancia la funzione successiva, la quale nasconde il messaggio … e così via se vogliamo creare animazioni più complesse.

Riutilizziamo il codice

Ora creaiamo una piccola classe che racchiuda il codice:

var CoolNotifier = new Class({
 initialize: function(trigger, notifier) {
 this.element = $(notifier);
 this.trigger = $(trigger);
 this.trigger.addEvent("click", this.notify.bindWithEvent(this));
 },
 notify: function(e) {
 if (e) e.preventDefault();
 this.element.setStyles({
 "opacity" : 0,
 "visibility" : "hidden"
 });
 this.element.get("morph").start({"opacity" : 1}).chain(
 function() { this.callChain.delay(1000, this) },
 function() { this.start({ "opacity": 0 }); }
 );
 }
});

// Et Voilà, per usarla sul click:
var myCoolNotifier = new CoolNotifier("trigger", "message");

// Per lanciare la funzione autonomamente
myCoolNotifier.notify()

Nulla ci vieta di fare in modo che anche la catena di funzioni da eseguire non sia dinamica passando un terzo parametro così da personalizzare l”effetto per ogni “notificatore” (nome orribile). A voi programmatori come implementare questa funzionalità :). Su mooshell la classe all”opera.