Revisión de la plantilla para plugins jQuery

16 May 2011

Tras un par de semanas de uso, Stefan Gabos ha actualizado la plantilla para plugins jQuery gracias a la sugerencias de otros desarrolladores sobre la base original.

Para la nueva versión, se ha tomado como inspiración el código generado por la aplicación Starter de Doug Neiner cuya estructura resulta algo más clara y manejable que la anterior.

Sin más, os facilito las dos versiones del código (con y sin comentarios) además de un ejemplo de uso que muestra cómo acceder a sus partes:

Código con comentarios

// remember to change every instance of "pluginName" to the name of your plugin!
;(function($) {
 
    // here we go!
    $.pluginName = function(element, options) {
 
        // plugin's default options
        // this is private property and is  accessible only from inside the plugin
        var defaults = {
 
            foo: 'bar',
 
            // if your plugin is event-driven, you may provide
            // callback capabilities for its events.
            // execute these functions before or after events of your
            // plugin, so that users may customize those particular
            // events without changing the plugin's code
            onFoo: function() {}
 
        }
 
        // to avoid confusions, use "plugin" to reference the current
        // instance of the object
        var plugin = this;
 
        // this will hold the merged default, and user-provided options
        // plugin's properties will be available through this object like:
        // plugin.settings.propertyName from inside the plugin or
        // element.data('pluginName').settings.propertyName from outside
        // the plugin, where "element" is the element the plugin is
        // attached to;
        plugin.settings = {}
 
        // reference to the jQuery version of DOM element the plugin is attached to
        var $element = $(element),
             element = element;    // reference to the actual DOM element
 
        // the "constructor" method that gets called when the object is created
        plugin.init = function() {
 
            // the plugin's final properties are the merged default
            // and user-provided options (if any)
            plugin.settings = $.extend({}, defaults, options)
 
            // code goes here
 
        }
 
        // public methods
        // these methods can be called like:
        // plugin.methodName(arg1, arg2, ... argn) from inside the plugin or
        // element.data('pluginName').publicMethod(arg1, arg2, ... argn)
        // from outside the plugin, where "element"
        // is the element the plugin is attached to;
 
        // a public method. for demonstration purposes only - remove it!
        plugin.foo_public_method = function() {
 
            // code goes here
 
        }
 
        // private methods
        // these methods can be called only from inside the plugin like:
        // methodName(arg1, arg2, ... argn)
 
        // a private method. for demonstration purposes only - remove it!
        var foo_private_method = function() {
 
            // code goes here
 
        }
 
        // fire up the plugin!
        // call the "constructor" method
        plugin.init();
 
    }
 
    // add the plugin to the jQuery.fn object
    $.fn.pluginName = function(options) {
 
        // iterate through the DOM elements we are attaching the plugin to
        return this.each(function() {
 
            // if plugin has not already been attached to the element
            if (undefined == $(this).data('pluginName')) {
 
                // create a new instance of the plugin
                // pass the DOM element and the user-provided options as arguments
                var plugin = new $.pluginName(this, options);
 
                // in the jQuery version of the element
                // store a reference to the plugin object
                // you can later access the plugin and its methods and properties like
                // element.data('pluginName').publicMethod(arg1, arg2, ... argn) or
                // element.data('pluginName').settings.propertyName
                $(this).data('pluginName', plugin);
 
            }
 
        });
 
    }
 
})(jQuery);

Código sin comentarios

;(function($) {
 
    $.pluginName = function(element, options) {
 
        var defaults = {
            foo: 'bar',
            onFoo: function() {}
        }
 
        var plugin = this;
 
        plugin.settings = {}
 
        var $element = $(element),
             element = element;
 
        plugin.init = function() {
            plugin.settings = $.extend({}, defaults, options)
            // code goes here
        }
 
        plugin.foo_public_method = function() {
            // code goes here
        }
 
        var foo_private_method = function() {
            // code goes here
        }
 
        plugin.init();
 
    }
 
    $.fn.pluginName = function(options) {
 
        return this.each(function() {
            if (undefined == $(this).data('pluginName')) {
                var plugin = new $.pluginName(this, options);
                $(this).data('pluginName', plugin);
            }
        });
 
    }
 
})(jQuery);

Ejemplo de uso

$(document).ready(function() {
 
    // attach the plugin to an element
    $('#element').pluginName({'foo': 'bar'});
 
    // call a public method
    $('#element').data('pluginName').foo_public_method();
 
    // get the value of a property
    $('#element').data('pluginName').settings.foo;
 
});

Conclusión

Esta estructura es algo más limpia que la anterior y, de nuevo, un patrón interesante que tener en cuenta a la hora de desarrollar nuestros plugins jQuery más complejos.

Además de este boilerplate, cabe recordar que tenéis más alternativas en la documentación oficial jQuery cuyo principal inconveniente es que no hacen separación entre los métodos públicos y privados.

Gracias a Armando Antón por el aviso.

Más:

Aún no tenemos debug!
Ningún marciano se ha comunicado.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *