Last active
August 29, 2015 14:24
-
-
Save lokothodida/d688afcf894ddb61209f to your computer and use it in GitHub Desktop.
jQuery Nested Plugins
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This piece of code illustrates how you can build a series of jQuery plugins | |
// nested on your own desired namespace. So if you have a plugin named 'plugin', | |
// it can have the signature: | |
// $(selector).plugin(opts) | |
// and there can exist jQuery plugins 'module1', 'module2', 'module3', ... which | |
// have the signatures: | |
// $(selector).plugin().module1(opts) | |
// $(selector).plugin().module2(opts) | |
// $(selector).plugin().module3(opts) | |
// These modules are written almost exactly like normal jQuery plugins bound | |
// directly to $.fn, but they only live within the 'plugin' namespace. | |
;(function($, window, document, undefined) { | |
// Your main plugin, as it would be defined on $.fn | |
// We alias $.fn.plugin with just @plugin to shorten our references to | |
// $.fn.plugin later on | |
var plugin = $.fn.plugin = function(opts) { | |
// If no arguments are passed, we will return the sub plugins | |
// using the @getModules singleton method which we will later define | |
if (!arguments.length) { | |
return plugin.getModules(this, plugin.modules); | |
} | |
// Now you can define your plugin as usual... | |
// E.g: | |
var init = function(i, elem) { | |
var $elem = $(elem); | |
// ... | |
}; | |
// ... | |
return this.each(init); | |
}; | |
// This is the method that does the heavy lifting | |
// It will take a @context (a jQuery Element), and @modules -- which will be an | |
// object literal of jQuery plugins -- and return a new object literal wherein | |
// the references to @this in those plugins has been fixed to the @context | |
plugin.getModules = function(context, modules) { | |
var api = {}; // where the altered methods will be stored | |
$.each(modules, function(name, module) { | |
// Module name is the same, but the function will instead call @body with | |
// the context shifted to @context (and take the same arguments) | |
api[name] = function() { | |
return module.apply(context, arguments); | |
}; | |
}); | |
return api; | |
}; | |
// Initialize the @modules object | |
plugin.modules = {}; | |
// Now each of your modules are defined on the @modules literal as though they | |
// were normal jQuery plugins; their references to @this will be fixed by the | |
// @getModules method (called when your main plugin is initialized) | |
// Module 1 | |
// Accessed with: $(selector).plugin().module1(opts) | |
plugin.modules.module1 = function(opts) { | |
// Code for this plugin ... | |
var init = function(i, elem) { | |
// ... | |
}; | |
// By returning this.each, module1 is chainable with the plugins on the $.fn | |
// namespace | |
// E.g. you can call $(selector).plugin().module1(opts1).css(opts2); | |
return this.each(init); | |
}; | |
// Module 2 | |
// Accessed with: $(selector).plugin().module2(params) | |
plugin.modules.module2 = function(opts) { | |
// Code for this plugin ... | |
var init = function(i, elem) { | |
// ... | |
}; | |
// By returning this.each(...).plugin, module2 is chainable with the plugins | |
// on the $(...).plugin() namespace | |
// E.g. you can call $(selector).plugin().module2(opts1).module1(opts2); | |
return this.each(init).plugin(); | |
}; | |
// Module 3 | |
// Accessed with: $(selector).plugin().module3(params) | |
plugin.modules.module3 = function(opts) { | |
// Code for this plugin ... | |
// You can have as many modules as you need | |
}; | |
})(jQuery, window, document); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment