jQuery plugins come in all shapes and sizes. They perform very simple
or very complex tasks depending on their intended use. When it comes
time for you to design your own plugin, its really important to
understand what patterns other developers use and what will best suits
your needs.
As a side note, I have built a number of plugins for my own projects and client work that will
never be released.
The jQuery community needs to stop thinking of plugins only as
releasable, open-source projects, and start thinking of them instead as a
reusable pieces of code that can help optimize and
DRY up a complex website. Take this little plugin as an example:
$.fn.notice = function(){ |
return this.slideDown(500).delay(4000).slideUp(500); |
It simply abstracts the animation for displaying a notice (using
jQuery 1.4). Would I ever release this on an open source site? Of course
not! But it is still a fully functioning jQuery plugin that can be used
over and over throughout a website.
Design Pattern Series Overview
- Basics & Structure (this article)
- Options & Updating
- Callbacks & Custom Events
- Misc. General Practices
Basics
Filename
Every jQuery plugin sits in its own JS file, and is normally named using the following pattern:
Released plugins often also have a version number:
jquery.pluginname-1.3.min.js |
If you end up building a lot of plugins for your website, consider
also including a namespace to keep all your files together (And of
course you would combine and minify them for production, right?):
jquery.mysite.pluginname.js |
jquery.mysite.pluginname.js |
Basic File Layout
After any comments you choose to put at the top of your file, the
very next thing you should have is a self executing anonymous function
that will actually wrap your entire plugin. Say what!? Don’t worry, you
have seen it before, and it looks like this:
This gives your plugin a private scope to work in, and also allows your plugin to be used with
$.noConflict mode without creating a problem. By passing
jQuery into the function, the
$ will equal jQuery
inside the function even if
$ means something different outside your plugin.
Structure
There are three basic structures you will see when you look at released plugins:
Contained Function
In this structure, (almost) all the code to run your plugin is
contained within the function used to call your plugin. This is the most
common format:
$.fn.myPlugin = function(){ |
return this.each(function(){ |
You
should use this this structure when you are
writing a simple plugin that acts once upon the jQuery result set on
each execution. For complex plugins that need to maintain an adjustable
state, you should consider the “Class and Function” structure.
Class and Function
In this structure, a class is used and an instance is created for
each DOM element in the result set. You may see these objects attached
in some way to the DOM elements they modify:
var MyClass = function(el){ |
$el.data('MyClass', this); |
$.fn.myPlugin = function(){ |
return this.each(function(){ |
You
should use this structure if you need to be able
to access the object later that is associated with a DOM element. It is
far easier to attach a single object vs several key/value pairs using
the
data() method. In this approach, you can access the object by calling
$('selector').data('MyClass').
This functions more like a widget and is a plugin that maintains state
and can adjust its state on the fly (Learn how in the next article.).
Note: Widget Factory: The next release of
jQuery UI is going to see the addition of a Widget Factory that will be
designed to specially assist in developing widget-like plugins.
Extend
In my opinion, this is the least idiomatic way to create a jQuery plugin. It uses the
jQuery.fn.extend method instead of
jQuery.fn.pluginName:
return this.each(function(){ |
myOtherPlugin: function(){ |
return this.each(function(){ |
You will find this structure helpful if you need to add a
large number
of plugin methods to jQuery. I would contend, however, that if your
plugin needs to add that many methods, there may be a better way to
structure its implementation.
I feel the extend method is used more by programmers transitioning from other JS libraries. I personally find the simple
$.fn.pluginName = structure to be easier to read, and more in line with what you will normally see in jQuery plugins.
Up Next
In the next part of this series, we will look at passing options and
providing methods for updating settings and functionality after a plugin
has been called.