Back in September of 2009 Microsoft decided to ship and support the JavaScript library jQuery with Visual Studio. One of the great things about jQuery is how well it shields the developer from all the cross-browser differences that make it so hard to just write some code that works reasonably in all browsers. jQuery is small (20KB), fast, and uses a DOM selector API to its advantage. It is also easily extensible. This has lead to the creation of hundreds of plugins for added functionality. By using just the plugins you need, you can avoid the bloat of some of the other more fleshed out JavaScript libraries.
There are plugins for practically everything you can think of. But if you can't find a plugin to fill your need, it is a fairly straightforward process to write your own. Moreover, if you find yourself writing similar code again and again, you should probably look into turning that code into a plugin. That way, if you need to update the code, you only have to do it in one place. You can also use plugins as inside of plugins to speedup development.
First of all you'll need to enclose your plugin code inside a jQuery namespace closure. That will look like this:
(function($) {
})(jQuery);
Basically we're creating a JavaScript closure, passing in jQuery as a parameter and aliasing it to the dollar sign. Now, depending on what your plugin will do, there are several ways to implement your plugin. You can attach it directly to the jQuery object, or you can make it an extension of the jQuery object. If all you're doing is invoking a method and passing it some parameters, then attaching it directly to the jQuery object is sufficient. However, if you want it to inherit all the properties of the jQuery object and be chainable, you'll want to extend the jQuery object.
Attaching a Plugin to the jQuery Object
(function($) {
$.nameOfYourPluginHere = function() {
// Define method here.
};
})(jQuery);
This is a nice start. But we probably would expect the need for some basic initialization. We can do this by setting up some default values which the user can override. Here's how that would look:
(function($) {
$.nameOfYourPluginHere = function(options) {
$.nameOfYourPluginHere.defaults = {
value1 : "",
value2 : "",
value3 : ""
};
var options = $.extend($.nameOfYourPluginHere.defaults, options);
// Define method here.
};
})(jQuery);
Now all that's left is to do something with our plugin. Usually you would do something to a collection of nodes returned by a selector query. This would look something like this:
(function($) {
$.nameOfYourPluginHere = function(options) {
$.nameOfYourPluginHere.defaults = {
targetElems : "a",
value1 : "",
value2 : "",
value3 : ""
};
var options = $.extend($.nameOfYourPluginHere.defaults, options);
// Define method here.
$($.nameOfYourPluginHere.defaults.targetElems).each(function() {
var $this = $(this);
$this.css({"background-color" : "Yellow", "color" : "Red"});
});
};
})(jQuery);
In the above example we have a targetElems default value of "a", but we could pass in any selector we want:
$.nameOfYourPluginHere({targetElems : "#globalNav li a"});
Also you might want to attach an event to each node:
(function($) {
$.nameOfYourPluginHere = function(options) {
$.nameOfYourPluginHere.defaults = {
targetElems : "a",
value1 : "",
value2 : "",
value3 : "",
speed : "slow"
};
var options = $.extend($.nameOfYourPluginHere.defaults, options);
// Define method here.
$($.nameOfYourPluginHere.defaults.value1).each(function() {
var $this = $(this);
$this.click(function() {
// Do whatever you need to do with $this as each individual node:
$this.doSomethingHere(speed);
});
});
function doSomethingHere(speed) {
// Define method using speed here.
}
};
})(jQuery);
Making Your Plugin an Extension of jQuery
A limitation to the above plugin is that we can chain it like normal jQuery methods. In order to accomplish that we need to make our plugin an extension of the jQuery object. We can do this very easily by making the plugin an extension of the jQuery.fn method. As an example, let's make a hilite plugin:
(function($) {
$.fn.hilite = function(options) {
// Define some defaults.
$.fn.hilite.defaults = {
foreground: 'red',
background: 'yellow'
};
// Allow the user to override the defaults:
var opts = $.extend($.fn.hilite.defaults, options);
// Iterate over the collection while returning each item.
return this.each(function() {
$this = $(this);
// Define what you want to do with your items.
$this.css({
backgroundColor: opts.background,
color: opts.foreground
});
});
};
})(jQuery);
We can now inovke our plugin and chain other jQuery methods to it to get more complex results:
$(document).ready(function() {
$("#sideColumn p").hilite({background: "red", foreground: "yellow"}).
css({"font-size" : "24px"}).animate({ "margin-left" : "100px"});
});