Thursday, October 13, 2011

jQuery Plugin Patterns

Here are some jQuery Plugin Patterns, the list is still expanding.  This post is mostly for my own reference, but just blog it here in case someone might be helped from this.

One note before you start doing your super fancy plugin.  The 'this' keyword in the immediate scope of the plugin is referring to the jQuery object, so there is no need to do $(this).  


Basic Form


  $.fn.yourPlugin = function(options, callback) {
    // ...
  };



Wrapped in Closure to create namespace

;(function($, window, undefined) {
  $.fn.yourPlugin = function(options, callback) {
    // ...
  };
})(jQuery, window);



Define multiple related functions (or related plugins) in one shot. 

;(function($, window, undefined) {
  $.extend($.fn, {
     yourPlugin: function() {
        // ...
     },
     yourSecondPlugin: function() {
        // ...
     }
  });
})(jQuery, window);


Prototype way

;(function($, window, undefined) {
  var pluginName = 'yourPlugin', pluginDefaultOptions = {};

  function Plugin(el, options) {
    this.element = el;
    this.options = $.extend({}, pluginDefaultOptions, options);
    this._name = pluginName;
    this.init();
  }  

  Plugin.prototype.init = function() {
    // ...
  }

  // make sure only one instance is instantiated
  $.fn[pluginName] = function ( options ) {
    return this.each(function () {
       if (!$.data(this, 'plugin_' + pluginName)) {
           $.data(this, 'plugin_' + pluginName,
           new Plugin( this, options ));
       }
    });
  }

})(jQuery, window);


Object Literal way

;(function($, window, undefined) {

    $.fn.pluginName = function(method) {

        var methods = {
            init : function(options) {
                this.pluginName.settings = $.extend({}, 
                                             this.pluginName.defaults, 
                                             options);
                return this.each(function() {
                    var $element = $(this), 
                         element = this;  
                    // ...
                });
            },

            my_public_method: function() {
                // ...
            }
        }

        var helpers = {
            my_private_method: function() {
                // ...
            }
        }

        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error( 'Method "' +  method + '" does not exist in pluginName plugin!');
        }
    }

    $.fn.pluginName.defaults = {
        foo: 'bar'
    }

    $.fn.pluginName.settings = {}

})(jQuery, window);



Modified Object Literal way

;(function($, window, undefined){
    $.fn.packagename = function(options, callback){
        
        var params = $.extend({},
                        $.fn.packagename.default_options, options), 
                        $that = $(this);
        
        if($.isFunction(options)){
            callback = options;
            options = {};
        } 
        
        var methods = {
            init: function() {
               // ... 
            }
        }
        
        methods.init.apply(this,[]);      
    }
    
    $.fn.packagename.default_options = {
       src: ".data" 
    }
})(jQuery, window);






1 comment:

  1. Wow, this list is a great side by side of the plugin structures I've checked out. I haven't yet seen a great example of each of them which demonstrates pros and cons of each method. In fact, there's often more talk about the architecture benefits of each method rather than anything about a real world implementation. I guess I learn by doing, not by theorising.

    ReplyDelete