A Plugin Development PatternRead 107 comments by Mike Alsup
I ' ve been developing jQuery plugins for quite a while now, and I ' ve become rather comfortable with a particular style of P Lugin development for my scripts. This article was meant to share the pattern that I ' ve found especially useful for plugin authoring. It assumes you already has an understanding of plugin development for JQuery; If you ' re a novice plugin author, please review thejquery Authoring guidelines first.
There is a few requirements that I feel this pattern handles Nicely:claim with a single name in the JQuery namespace ACC EPT an options argument to control plugin behavior provide public access to default plugin settings provide public access To secondary functions (as applicable) Keep private functions Private support the Metadata Plugin
I ' ll cover these requirements one by one, and as we work through them we'll build a simple plugin which highlights text. Claim only a single name in the JQuery namespace
This implies a single-plugin script. If your script contains multiple plugins, or complementary plugins (like $.fn.dosomething () and $.fn.undosomething ()) Then You ' ll claim multiple names is required. But in the general when authoring a plugin, strive to is only a single name to the hold all of its implementation details.
In our example plugin we'll claim the name "Hilight". PLAIN TEXT JavaScript:
Plugin definition $. fn. hilight = function () {//Our plugin implementation code goes here.};
And our plugin can is invoked like This:plain TEXT JavaScript:
$ (' #myDiv '). Hilight ();
But what if we need-to-break up your implementation into more than one function? There is many reasons to does so:the design may require it; It may result in a simpler or more readable implementation; And it may yield betterOO semantics.
It ' s really quite trivial to break up the implementation into multiple functions without adding noise to the namespace. We do this by recognizing, and taking advantage of, the fact thatfunctions is first-class objects in JavaScript. Like any other object, functions can is assigned properties. Since We have already claimed the ' hilight ' name in the JQuery prototype object, any other properties or functions that we Need to expose can is declared as properties on our "hilight" function. More on this later. Accept An options argument to control plugin behavior
Let's add support to our Hilight plugin for specifying the foreground and background colors to use. We should allow options like these to be passed as a options object to the plugin function. For Example:plain TEXT JavaScript:
Plugin definition $. fn. hilight = function (options) {var defaults = {foreground: ' Red ', background: ' Yellow '}; Extend Our default options with those provided. var opts = $.extend (defaults, options); Our plugin implementation code goes here. };
Now our plugin can is invoked like This:plain TEXT JavaScript:
$ (' #myDiv '). Hilight ({foreground: ' Blue '});
provide public access to default plugin settings
An improvement we can, and should, make to the code above are to expose the default plugin settings. This was important because it makes it very easy for plugin users to override/customize the plugin with minimal code. And this is where we begin to take advantage of the function object. PLAIN TEXT JavaScript:
//Plugin definition $. fn. hilight = function (options) { //Extend our default Optio NS with those provided. //Note that the first, ARG to extend are an empty object- //This is to keep from overriding our "defaults" Object. var opts = $.extend ({}, $. fn. hilight. defaults, options); //Our plugin implementation code goes here. }; Plugin defaults-added as a property on our plugin function $. fn. Hilight. Defaults = { foreground: ' Red ', background: ' Yellow '};
Now the users can include a line like this in their scripts:plain TEXT JavaScript:
This need is called once and does not//has to is called from within a ' ready ' block $. fn. Hilight. Defaults. foreground = ' Blue ';
And now we can call the plugin method like this and it'll use a blue foreground color:plain TEXT JavaScript:
$ (' #myDiv '). Hilight ();
As can see, we ' ve allowed the user to write a single line of code to alter the default foreground color of the plug In. And users can still selectively override this new default value when they want:plain TEXT JavaScript:
//Override PL Ugin default foreground color $. fn. Hilight. Defaults. foreground = ' Blue '; ...//Invoke plugin using new defaults $ ('. Hilightdiv '). Hilight (); ...//override default by passing options to plugin method $ (' #green '). Hilight ({ foreground: ' Green '});
provide public access to secondary functions as applicable
This item goes hand-in-hand with the previous item and are an interesting-to-extend your (and to let plugin E Xtend your plugin). For example, the implementation of We plugin may define a function called "format" which formats the hilight text. Our plugin could now look like this, with the default implementation of the format method defined below the Hilight function . PLAIN TEXT JavaScript:
//Plugin definition $. fn. hilight = function (options) { //iterate and reformat EAC H matched element return this. each (function () { var $this = $ (this), //... var markup = $this. HTML ( ); //Call our Format function markup = $. fn. Hilight. Format (markup); $this. HTML (markup); }); }; Define our Format function $. fn. Hilight. format = function (txt) {' return ' <strong> ' + txt + ' </strong> ';};
We could has just as easily supported another property on the options object, allowed a callback function to be PR ovided to override the default formatting. That ' s another excellent-to-support customization of your plugin. The technique shown here takes this a step further by actually exposing the format function so which it can be redefined. With this technique it would is possible for others to ship their own custom overrides of your pluginנin other words, it means others can write plugins for your plugin.
Considering the trivial example plugin we ' re building in this article, if you are wondering when this would ever is useful . One real-world example is Thecycle Plugin. The Cycle Plugin is a slideshow Plugin which supports a number of built-in transition effectsנscroll, slide, fade, etc. B UT realistically, there is no-define every single type of effect so one might wish to apply to a slide transition . And that ' s where the This type of extensibility is useful. The Cycle Plugin exposes a "transitions" object to which users can add their own custom transition definitions. It ' s defined in the plugin like This:plain TEXT JavaScript:
$. fn. cycle. Transitions = {//...};
This technique makes it possible for others to define, and ship transition definitions, plug-in to the Cycle Plugin. Keep Private Functions Private
The technique of exposing part of your plugin to being overridden can be very powerful. But the need to think carefully on what's parts of your implementation to expose. Once it ' s exposed, you need to keep on mind so any changes to the calling arguments or semantics could break backward comp Atibility. As a general rule, if you ' re not sure whether to expose a particular function, th