I plugin jQuery possono sfruttare le potenzialità dell'OOP di JavaScript per automatizzare la creazione di questi ultimi. A partire da Douglas Crockford fino ad Addy Osmani sono stati resi noti diversi design pattern che possono essere applicati ai plugin jQuery. In questo articolo vedremo uno di questi pattern.
Per prima cosa creiamo un oggetto letterale che conterrà la logica e le routine del nostro plugin:
var PluginFactory = {
// Metodo di inizializzazione. I parametri sono 1) le opzioni del plugin 2) l'elemento associato
init: function(options, elem) {
// Crea le opzioni del plugin
this.options = $.extend({}, this.options, options);
this.elem = elem; // Riferimento all'elemento DOM associato al plugin
this.$elem = $(elem); // Riferimento all'elemento jQuery associato al plugin
this._build(); // Invoca l'azione principale del plugin
return this; // In questo modo possiamo concatenare i metodi come oggetto.metodo1().metodo2()...
},
options: {
name: 'Test' // Opzioni predefinite del plugin
},
_build: function() { // Azione principale del plugin
this.$elem.html('<p>' + this.options.name + '</p>');
},
method: function(msg) { // Azione secondaria del plugin
this.$elem.append('<p>' + msg + '</p>');
}
};
A questo punto ci occorre un metodo helper per creare ed inizializzare un nuovo oggetto. Le versioni più recenti di JavaScript implementano il metodo Object.create()
, ma i browser più obsoleti non lo supportano. Dobbiamo quindi usare il pattern di Douglas Crockford:
if (typeof Object.create !== 'function') {
Object.create = function(o) {
function F() {}
F.prototype = o;
return new F();
};
}
Quindi possiamo finalmente creare la funzione che genererà i plugin:
$.plugin = function(name, object) { // name è il nome del plugin, object è l'oggetto PluginFactory
// Il nome del plugin viene assegnato all'oggetto $.fn tramite la notazione a parentesi quadre per evitare errori
$.fn[name] = function(options) {
return this.each(function() { // this è l'oggetto jQuery
if (!$.data(this, name)) { // verifichiamo che il nostro oggetto non sia già stato associato tramite $.data()
// associamo l'oggetto, lo creiamo e lo inizializziamo con le opzioni del plugin
$.data(this, name, Object.create(object).init(
options, this));
}
});
};
};
Esempio:
// Creo il plugin $(elemento).test()
$.plugin('test', PluginFactory);
$('#test').test({
name: 'Gabriele'
});
// Ottengo l'oggetto associato al plugin tramite .data()
var instance = $('#test').data('test');
// Invoco il metodo dell'oggetto
instance.method('method()');
Potete visionare l'esempio finale in questa pagina.