Simple jQuery Plugin Tutorial

Author : Scott Lewis

Tags : jQuery, Javascript

In this article, I will teach you how to develop a standard jQuery plugin. I will keep things as simple as possible and will only build a very trivial plugin, but through this example I will cover all of the important aspects of jQuery plugin development.

Before we begin, let’s outline exactly what we are going to build.

Covered in this article

Avoiding Library Conflicts in JQuery

It is not uncommon for a web site to use multiple Javascript libraries, for instance jQuery and Prototype. Since several of the popular JavaScript libraries use the $ (dollar sign) namespace, conflicts can occur causing one or all of the libraries to break.

JavaScript provides us with a handy technique for avoiding conflicts: the anonymous function. Wikipedia defines an anonymous function like so:

"In computing, an anonymous function is a function (or a subroutine) defined, and possibly called, without being bound to an identifier."

This means that the function will not be stored in a variable or otherwise named. The function will receive a single argument, the $ variable. It is important to note that the $ variable inside the function will be unique in the function’s scope and will not conflict with any other variable by the same name. It will also contain a reference to the jQuery object because we will pass the jQuery object to our anonymous function.

/**
 * Create an anonymous function to avoid library conflicts
 */
(function($) {
    // The body of our plugin will go here
})(jQuery);

This may all look and sound confusing but it’s actually very simple. What we have done is identical to this:

var doSomethingAmazing = function($) {
    // Do something
};
doSomethingAmazing(jQuery);

The only difference is that in the first case, we don’t bother with naming the function, thus the term "anonymous". We simply create and execute the function in a single, efficient step.

Iterating Collections of Elements in jQuery

One of the efficiencies of using jQuery is the ability to apply a bit of code to all elements matching an element without explicitly selecting them all and looping through them. All you do is pass jQuery a selector that indicates which elements on which to act, and jQuery takes care of the iteration.

In order to have jQuery handle the iteration, you have to add your plugin to the jQuery.fn (pronounced "effin" according to jQuery’s site) object rather than just add it as a function on the jQuery object.

The difference is between this:

$.doSomethingAmazing();

And this:

$("p").doSomethingAmazing();

There are two ways to add your plugin to the jQuery.fn object: by explicitly defining a property on the object with your plugin name (the preferred way) or by using jQuery.extend() to merge a plugin object onto the jQuery.fn object. Personally I think the first technique is probably more efficient in terms of parsing but I have not tested this assumption. The official jQuery site uses the first technique so that is the one we will use. I mention the second technique simply to let you know that there is another way and you may see it elsewhere. Just be aware that both techniques are correct and both are acceptable.

(function($) {
    $.fn.doSomethingAmazing = function() {
        // Do some kick-ass stuff here
    };
})(jQuery);

Method Chaining jQuery Functions

Method chaining allows you to write more terse code by making the return value of each method the object on which the method is operating. This is the name for what is happening when you see something like this:

$(".hidden").fadeIn("slow").css("color", "#FFF");

Preserving method chaining is very easy to achieve in your plugin by doing the following:

(function($) {
    $.fn.doSomethingAmazing = function() {
        /**
         * Return the object to preserve method chaining
         */
        return this.each(function(i) {
            // Do some kick-ass stuff here
        });
    };
})(jQuery);

We are returning the element – stored in the this object – at the completion of each iteration.

Adding Options to Custom jQuery Plugins

Keeping your options open Your plugin may require some settings that will change depending on the context in which it is used. As a responsible developer, you know better than to hard-code values if it can be avoided and you want to allow users of your plugin to customize the look and/or behavior of the output to fit their needs, right?

Again, allowing for customization is very simple to implement. On the jQuery site, it is recommended that an object containing the various settings options be used as a single argument to the plugin rather than defining a long list of arguments. So we will pass a single argument named "options" to our plugin function.

(function($) {
    $.fn.doSomethingAmazing = function(options) {
        /**
         * Return the object to preserve method chaining
         */
        return this.each(function(i) {
            // Do some kick-ass stuff here
        });
    };
})(jQuery);

Didn’t I say it was simple?

We can’t just stop there, however. We want to make sure that there is a known default value of any settings.

(function($) {
    $.fn.doSomethingAmazing = function(options) {
        /**
         * Define some default settings
         */
        var defaults = {
            "color": "#F00",
            "font-weight": "bold"
        };
        /**
         * Return the object to preserve method chaining
         */
        return this.each(function(i) {
            // Do some kick-ass stuff here
        });
    };
})(jQuery);

Next, we need to merge any runtime options with the plugin’s default options.

(function($) {
    $.fn.doSomethingAmazing = function(options) {
        /**
         * Define some default settings
         */
        var defaults = {
            "color": "#F00",
            "font-weight": "bold"
        };
        /**
         * Merge the runtime options with the default settings
         */
        var options = $.extend({}, defaults, options);
        /**
         * Return the object to preserve method chaining
         */
        return this.each(function(i) {
            // Do some kick-ass stuff here
        });
    };
})(jQuery);

This next part can be a little tricky to follow if you are not very familiar with scoping in JavaScript. The this object in JavaScript refers to the current scope of execution. By current, I mean the scope in which the this keyword is used. It can also be a little tricky to keep track of which objects are and are not instances of the jQuery object.

If you look at line #17 in the code above, you will notice that the each method is being called on the this object. There is no native each method in JavaScript. The this object is an instance of the jQuery object, which defines the each method.

However, a reference to the this object inside the function being passed to the loop, does not refer to the same object as the this on which we are calling the each method. The outer reference to this refers to the instance of our plugin. Inside the function, this will refer to the current element in the iteration through the selected elements.

We can (and want to) wrap the current element in a jQuery instance by doing the following:

(function($) {
    $.fn.doSomethingAmazing = function(options) {
        /**
         * Define some default settings
         */
        var defaults = {
            "color": "#F00",
            "font-weight": "bold"
        };
        /**
         * Merge the runtime options with the default settings
         */
        var options = $.extend({}, defaults, options);
        /**
         * Return the object to preserve method chaining
         */
        return this.each(function(i) {
            var $this = $(this);
            // Do some kick-ass stuff here
        });
    };
})(jQuery);

We now have a fully-functional, albeit completely useless, jQuery plugin. I’m going to go ahead and finish this simple plugin to change the color and weight of any text contained in elements matching the selectors specified when the plugin is called, so you can see a finished plugin, but you can use the code above as the basis for creating a plugin to do anything you want. Just change the properties of the defaults object and add your code where it reads "Do something kick-ass here".

/**
 * Create an anonymous function to avoid library conflicts
 */
(function($) {
    /**
     * Add our plugin to the jQuery.fn object
     */
    $.fn.doSomethingAmazing = function(options) {
        /**
         * Define some default settings
         */
        var defaults = {
            "color": "#F00",
            "font-weight": "bold"
        };
        /**
         * Merge the runtime options with the default settings
         */
        var options = $.extend({}, defaults, options);
        /**
         * Iterate through the collection of elements and
         * return the object to preserve method chaining
         */
        return this.each(function(i) {
            /**
             * Wrap the current element in an instance of jQuery
             */
            var $this = $(this);
            /**
             * Do our kick-ass thing
             */
            $this.css("color", options.color);
        });
    };
})(jQuery);

Add Your Custom jQuery Plugin to Your Site

All that is left to do is add your plugin to your site and to call it. Adding this or any other jQuery plugin to your site is just a matter of linking to the JavaScript file that contains your plugin code.

NB: jQuery plugins must be loaded after the main jQuery file is loaded.

The accepted naming convention for jQuery plugins is jquery.pluginname.js, so for our example we will save our plugin code in a file named jquery.plugin-tutorial.js and upload it to our site.

Next, we will add the following code to our web page:

<script src="/path/to/jquery.js"></script>
<script src="/path/to/jquery.plugin-tutorial.js"></script>

Calling Your Custom jQuery Plugin

And finally, we need to call our plugin. So we add the following bit of code anywhere in the HTML of the page:

<script>
    $(function() {
        $("h2").doSomethingAmazing({
            "color": "blue",
            "font-weight": "bold"
        });
    });
</script>

In this article I demonstrated how to build a jQuery plugin. Even though the plugin I built was very trivial and quite useless in itself, it does demonstrate the essentials of how all jQuery plugins are built. You can use the example in this article to build much more complex plugins.

Posted in JavaScript | Tag: jQuery, Javascript

Pay it forward

If you find value in the work on this blog, please consider paying it forward and donating to one of the followign charities that are close to my heart.