One of the questions I normally get from jQuery learners (aside from why the hell .bind() doesn’t work on dynamically-added HTML elements) is how to write a jQuery plugin. So for this article, I thought I’d introduce a fairly simple step-by-step walkthrough of creating a jQuery plugin that allows us to make something like this really quickly:
Doing this using vanilla jQuery
Of course, you can pretty much do this just by using plain jQuery, just as you would do with most other jQuery functionality. Something like the following would suffice:
// yeap, I know that this code can be optimized a big deal. jQuery(function($){ // we create two DIVs which form the two parts of our message box var $header = $('<div/>').addClass('header').text('Some header'), $message = $('<div/>').addClass('message').text('Some message'); // we add the click handler that makes the message slide up and down $header.click(function() { $message.slideToggle('fast'); }); // finally, we stick those two DIVs inside some other element $('#foo').append($header).append($message); }); |
With something like that, you’ve pretty much managed to accomplish the same thing.
However, if we want to be able to reuse that piece of code on several other elements, it’d be a better idea to write out that whole jQuery logic into a plugin, so we can just call on it whenever we want.
The basics of extending jQuery
jQuery exposes two kinds of ways to extend it: one using the $ namespace, and the other using $.fn.
Extending the plain $ object allows you to define new utility functions. Adding a new utility function is as easy as just naming a new property:
// creating the "say" utility function $.say = function (message) { alert (message); }; |
We can then use that much like any other function by calling $.say('Bros before hoes.');, and it’ll behave as you’d expect it to.
An arguably more powerful way of extending jQuery is extending $.fn, which allows you to create new functions that act on wrapped objects (like, for example, .addClass()). You create new wrapper methods in much the same way you create utility functions:
$.fn.foobar = function () { this.text('foobar'); return this; } |
Inside a new wrapper function, the this object is set to the jQuery wrapped set that the method was called on. So if $('#foo').foobar(); is called, then this inside foobar() is set to $('#foo'). This way, you can manipulate the elements as you see fit.
One of the things you should make a mental note of is to return the this context after the function resolves, so that your new wrapper method is compatible with jQuery chaining. (That is, you can do something like $('#foo').foobar().addClass('bar');.)
Changing our original jQuery code into a plugin
Now that we’ve got the basics out of the way, it should be fairly straightforward to rewrite our code above into a bit of jQuery plugin functionality. Calling our new method slidingBox() and applying the necessary changes in code, we get something like:
(function($){ $.fn.slidingBox = function (header,message) { var $header = $('<div/>').addClass('header').text(header), $message = $('<div/>').addClass('message').text(message); $header.click(function() { $message.slideToggle('fast'); }); return this.append($header).append($message); }; })(jQuery); |
With that out of the way, we can then use that just by calling something like $('#foo').slidingBox('This is my header.','This is my message.');. With a bit of CSS styling, you’re more or less ready to go!
If you want a more interactive way of demo-ing the code discussed in this article, or if you want to tinker around with ready-made code a bit, then feel free to wreak havoc on a jsFiddle I prepared especially for this article. It’s got ready jQuery code, and some CSS to boot.
Read More
Discussion