When to Extend jQuery
More often than you might think. I have found that writing jQuery extensions is a clean and readable way to write not only plugins, but also application and page specific code. Recently there have been two scenarios where I found it appropriate to write some extensions.
The first is when you are using a plugin in multiple places and have a common way of invoking and interacting with it in your application. I was working with a modal window that was popped from multiple places, so I wrapped the modal plugin in my own extension that knew all the default settings and behaviors for the modal. That way my pages that used it could just invoke my plugin and not have to duplicate all the setup code. This is just an example to illustrate the technique, so please don't bother trying to execute it.
[js](function($) {
$.fn.extend({
openMyModal: function(options) {
//Merge the passed in and default settings, then call the plugin code.
this.popmodal($.extend($.logWorkoutResults.settings, options));
}
});
$.extend({logWorkoutResults: {
settings: {
someSetting: 'blah',
success: function() {
...
}
}
});
})(jQuery);[/js]
So the gist of what we're doing here is providing the common set of settings and function overrides in one place, but still allowing them to be overridden by the caller. The default settings and the passed in settings will be merged and then the plugin will be invoked. You would call it like this:
[js]$(".selector").openMyModal({ someSetting: 'blah blah' });[/js]
Pretty clean and easy to use, yet still easy to override if a certain page needs to change things. You can really go crazy with this, too. Since it is your extension just using a plugin, you can add all sorts of additional functionality.
The other time that it makes a lot of sense to write your own is when you find yourself writing loose functions that take one or more DOM elements as a parameter, or even if your function selects some elements and acts on them. For example, let's look at this plain old function call.
[js]MyPage.myFunction($("div.somestuff"), { parm1: 'value' });[/js]
Instead of having a loose function that depends on being passed a jQuery element, just rewrite your function to extend jQuery and it gets a whole lot cleaner.
[js]$("div.somestuff").myFunction({parm1: 'value'});[/js]The inside of the function is easy to change, too. The old one would have looked like this:
[js]var MyPage = {
myFunction: function(elements, settings) {
elements.each(function() {
//do stuff with 'this'
});
}
};[/js]
But now it will just look like this:
[js](function($) {
$.fn.extend({
myFunction: function(options) {
this.each(function() {
//do something with 'this'
});
}
});
})(jQuery);[/js]
So the implementation code doesn't look that much different, but the calling is a whole lot cleaner and easier to follow. You can just include that extension at the top of your page's js file or where it makes sense.