LearnWriting Your Own jQuery Plugins

Tracy Rotton
writes on March 18, 2013

jQuery is great. It’s cross-browser, easy to learn, and makes adding interactivity to your website a breeze. It also comes with plenty of plugins to do almost whatever you need it to do.

But what if you can’t find just the right plugin to suit your needs? Or you’re just looking to keep your project DRY by combining some oft-used functionality into one nice, neat package? The solution might be to roll your own plugin to meet exactly your needs.

Writing your own jQuery plugin isn’t as hard as it might seem at first. This tutorial will go through the process of writing a simple plugin, adding some options, and even perform a callback.

Setting Up

We’ll start with the old chesnut of programming tutorials, a “Hello, World!” plugin. Before we can do anything, we need to establish our file and link it to our HTML document. First, we’ll create our plugin file and put it in the “js” directory of our website. It’s traditional to start our filename with “jquery,” followed by the actual plugin name, so we’ll call this “jquery.hello-world.js”.

Our web directory.

Our “Hello, World!” plugin, snuggly next to our jQuery core file.

Next, we’ll need to make sure our plugin file, as well as it’s jQuery core big brother, are linked in our HTML file, so place the following two lines at the bottom of your HTML document, just before the closing </body> tag:

<script src="js/jquery-1.9.1.min.js"></script>
<script src="js/jquery.hello-world.js"></script>

The jQuery Plugin Structure

jQuery comes with all the necessary hooks to build your plugin file easily. But we still want to be mindful of good JavaScript practices, and make sure we keep everything inside a local scope. We’ll start with the very basic shell of a traditional jQuery plugin:

(function($) {

    $.fn.helloWorld = function() {

        // Future home of "Hello, World!"

    }

}(jQuery));

Let’s take a quick moment to understand what’s going on. By including everything in the (function() {}) self-enclosed JavaScript pattern, we’re making sure that all the variables in our plugin will stay safely outside of the global namespace. We don’t want to cause any collisions with any other JavaScript used on the page, after all.

The other thing you might notice is that we’re defining our plugin as if jQuery was in it’s “no-conflict” mode. Again, we’re seeking to avoid colliding with other JavaScript on the page, and thus we want to make sure that our plugin isn’t reliant on the default $, which could be used by another library.

Finally, $.fn is jQuery’s way of allowing you to define your plugin, which we’ve named helloWorld. With all of our pieces in place, let’s actually do something!

Making Our Plugin Do Something

For our plugin, we’re going to do something pretty silly, but also simple enough for our demonstration purposes, and that is to change all the text for the acted upon elements with (what else?) the text “Hello, World!”.

(function($) {

    $.fn.helloWorld = function() {

        this.each( function() {
            $(this).text("Hello, World!");
        });

    }

}(jQuery));

When we’re invoking the plugin by attaching it to a jQuery selector, the object we’re acting upon is already a jQuery object, so we don’t need to wrap it in the $(this) structure you’re used to. However, once we start looping through each instance of the matching selector, we use the $(this) structure as we would any time we ran our selectors through $.each().

Suppose we wanted to change the text of all of our <h2> headers on the following page:

A screenshot of our web page before we run our "Hello, World!" plugin.

Our web page, ripe for the text swapping via jQuery.

We would invoke the plugin as you’re already familiar, like so:

<script>
$(document).ready( function() {
    $('h2').helloWorld();
});
</script>

To yield this:

A screenshot of our webpage with the <h2> headers swapped out with "Hello, World!"

Seems silly, I know, but we’ve now replaced all the <h2> headers with “Hello, World!”

We’re not quite done yet. While our plugin technically works, it’s living in its own little isolated world. That is, if you try and chain another jQuery action onto it, nothing’s going to happen because our plugin has led to a dead end. To fix this, be sure to return the results of the plugin as it loops through the DOM elements:

(function($) {

    $.fn.helloWorld = function() {

        return this.each( function() {
            $(this).text("Hello, World!");
        });

    }

}(jQuery));

And congratulations! You’ve just written you’re first jQuery plugin!

But Wait, There’s More!

Now that you’re all happy that you’ve built your jQuery plugin, your boss comes back and says that they need to be able to translate the site into Spanish. Uh oh, what do we do now?

Well, we could start by just adding an argument. Let’s take our plugin above, and instead of hard-coding the text into the plugin, we can replace it with a variable and pass that along when we invoke the plugin.

(function($) {

    $.fn.helloWorld = function( customText ) {

        return this.each( function() {
            $(this).text( customText );
        });

    }

}(jQuery));

There, now we can pass any text we’d like to our plugin. Our offices in Madrid have given us the Spanish translation we need, which we now use as the parameter of our plugin:

<script>
$(document).ready( function() {
    $('h2').helloWorld('¡Hola, mundo!');
});
</script>

Our web page now looks like this:

Screenshot of our "Hello, World!" plugin in Spanish.

Our plugin, with “Hello, World!” translated into Spanish.

Complete Customization FTW

But already we’re a little nervous. What if no text was passed when we called the plugin? As it’s written, the plugin would simply blank out the text of our matched elements, and we probably don’t want that. Also, our boss has already come back to us once asking to make a variable. What if he wants more customization options? Simply adding options ad infinitum isn’t going to work in the long term. A more future-proof solution is the options object.

We already know that the specific text needs to be customizable. Now our boss is asking that the text color and font style be customizable as well. (Yes, I know these are simple options to chain onto our selector via built-in jQuery functions, but go with me here.) Let’s add an options object to our plugin, along with some sensible defaults using the $.extend method:

(function($) {

    $.fn.helloWorld = function( options ) {

        // Establish our default settings
        var settings = $.extend({
            text         : 'Hello, World!',
            color        : null,
            fontStyle    : null
        }, options);

        return this.each( function() {
            // We'll get back to this in a moment
        });

    }

}(jQuery));

Now we have a settings object that, when the plugin is invoked devoid of any parameters, will use what we’ve established as the default text. We also have two other properties of our settings object, “color” and “fontStyle”, that have no default beyond null. For this plugin, we don’t need to establish any color or font style beyond what is laid out in our CSS, but they’re there for the overriding if we want. We just have to make use of them:

return this.each( function() {
    $(this).text( settings.text );

    if ( settings.color ) {
        $(this).css( 'color', settings.color );
    }

    if ( settings.fontStyle ) {
        $(this).css( 'font-style', settings.fontStyle );
    }
});

Since the purpose of this plugin is to replace text, it makes sense to always replace the text with whatever is provided, which is why it also makes sense to provide a default value so that something appears if the plugin is invoked without any options. But the color and font style options are tested for and only acted upon if they are provided.

Our boss has come back and says now they’re going to translate the site into French, and beyond that they want the text to be blue and italic. Fortunately, our plugin can now handle all these requests:

$('h2').helloWorld({
    text        : 'Salut, le monde!',
    color       : '#005dff',
    fontStyle   : 'italic'
});
A screenshot of our web page, now in French with blue, italic text.

With several options available to us, our plugin can now speak French, and even change the appearance of the text.

Et voilà! We now have a plugin with a number of possible objects, and the ability to easily add more (or subtract what’s there) in the future without impacting legacy users of the plugin. Hooray for maintainability!

But our boss has come back with yet another request: once the plugin has completed whatever task it was called to do, it should sound an alert informing us of that fact. For this, we have two options: either quit because our boss has obviously never heard of a requirements document, or go the less drastic route and give our plugin the ability to handle callbacks.

Callbacks are options to JavaScript functions that are themselves JavaScript functions. They’re also not unique to jQuery. Again, it may seem like it would be a complicated thing to do, but actually it’s quite simple.

All we need is to establish one more variable in our options object:

// Establish our default settings
var settings = $.extend({
    text         : 'Hello, World!',
    color        : null,
    fontStyle    : null,
    complete     : null
}, options);

Now we have a “complete” variable to perform an action when, well, our plugin completes its action. To invoke it, we’ll want to make sure that what we’re given is actually a function. Fortunately, jQuery helps us with this with the $.isFunction test:

return this.each( function() {
    // Our plugin so far

    if ( $.isFunction( settings.complete ) ) {
        settings.complete.call( this );
    }
});

On the invocation side, our code becomes:

$('h2').helloWorld({
    text        : 'Salut, le monde!',
    color       : '#005dff',
    fontStyle   : 'italic',
    complete    : function() { alert( 'Done!' ) }
});

And as a result, we see our callback as our plugin is executed:

Screenshot of our web page displaying an alert.

Our plugin now displays an alert every time it executes, thanks to our callback.

Conclusion

Custom jQuery plugins are a great option when you know you’re going to be doing a lot of the same things over and over in your JavaScript. By writing your own jQuery plugin, you’re both keeping your code DRY and your global namespace nice and clean.

If you’d like to play around with the code from this example, you can grab it from my GitHub.

50 Responses to “Writing Your Own jQuery Plugins”

  1. Try moving the map or changing your filters.

  2. cyntechtic on January 2, 2017 at 5:46 am said:

    Your html page has the script below

    jQuery(document).ready( function($) {
    $(‘h2’).helloWorld({
    text : ‘Salut, le monde!’,
    color : ‘#005dff’,
    fontStyle : ‘italic’,
    complete : function() { alert(‘Done!’); }
    });
    });

    if you need to change the text regular how do you pass the text argument without hard coding your html page source code.

  3. Thanks for sharing this article!
    Really Awesome 🙂

  4. Sadaf Aslam on August 31, 2016 at 10:00 pm said:

    Easy to understand good job please keep it up:)

  5. Very nice tutorial, easier to understand than the jquery site. Thx!

  6. himansu on March 14, 2016 at 12:25 am said:

    Thanks a lot. It’s a very cool tutorial. Explained very nicely , Thanks a lot again.

  7. Very great tutorial. very useful.

    Thanks for sharing

  8. Really nice article on how to write your own jquery plugins. There is this awesome site which provides most used plugins on the web which I really use when I’m looking for other pre written jquery plugins @ http://jqueryplugins.net

  9. That is a cool tutorial even after searching or a while seeking the patterns for writing jQuery plugins, this was the most robust simple pattern explained.

  10. ブランドスーパーコピーバッグ、財布、時計
    業界最高峰のブランドコピー 激安、コピーブランド、スーパーコピーブランド(N級品)通販専門店!ブランドコピー,コピーブランド,スーパーコピーブランド,ブランドコピー 激安,偽物ブランド、偽物のバッグ、腕時計、財布など激安で買える!全部のスーパーコピー販売品物のなかで私達のブランド激安が一番有名です http://www.gowatchs.com/brand-237.html

  11. Thanks for your explanation. It really help me a lot. Good article!!!

  12. Awesome Tracy Rotton. You helped me to under stand the concept in the easiest way possible. Thankz

  13. gjjjjjjjgjhjj on September 7, 2015 at 9:52 am said:

    ffdsf fffdfsf fsdfff dggg
    gfddfgfgg

  14. thanks. i love it.

  15. Nice blog.

    It helps me to clear lot of things about jQuery plugin

  16. Good Developing Idea of Jquery Plugin, I truly like it.

  17. Thanks for this valuable article, it is really useful. Neat explanation. Great job. Thank you

  18. Shrinivasan on September 21, 2013 at 10:34 am said:

    Neat explanation, wish I had seen this long time ago!

  19. cinderella on September 8, 2013 at 11:13 pm said:

    thanks for the article;it’s helpful

  20. very nicely explained and easy for beginners without assuming we know each step , thanks a million

  21. Good explanations ! Great job !

  22. I thought it was great. There were very subtle things here that the jQuery site was missing explanation wise, and it made understanding plugin development 10x easier

  23. if ( settings.color ) {
    $(this).css( ‘color’, settings.color );
    }

    I don’t think you need the text above.

    Writing this works because of the $.extend functionality
    $(this).css( ‘color’, settings.color ); <— this works without the if test above.

  24. Hi Tracy,

    I may have not have the code above correct but this does not work:
    $(‘p’).helloWorld({
    text : ”,
    color : ‘#005dff’,
    fontStyle : ‘italic’,
    complete : function() { alert( ‘Done!’ ) }
    });

    In other words when I pass a blank string of text I thought I should get Hello World, but I don’t. I am using a p selector but it shouldn’t matter. Can I find all the code in a zip file?

    • I may have asked this before, in case anyone else can’t figure this out either you are setting the text to nothing and nothing gets printed. If you want to leave the original text the way it is then do not include the name / value pair of text/value meaning this:

      $(‘p’).helloWorld({
      color : ‘#005dff’,
      fontStyle : ‘italic’,
      complete : function() { alert( ‘Done!’ ) }
      });

    • My function is as follows and done/complete function works fine:

      (function ($) {

      $.fn.helloWorld = function (options) {

      // Establish our default settings
      var settings = $.extend({
      text: ‘Hello, World!’,
      color: null,
      fontStyle: null,
      complete: null
      }, options);

      return this.each(function () {
      $(this).text(settings.text);

      if (settings.color) {
      $(this).css(‘color’, settings.color);
      }

      if (settings.fontStyle) {
      $(this).css(‘font-style’, settings.fontStyle);
      }

      if ($.isFunction(settings.complete)) {
      settings.complete.call(this);
      }
      });
      }

      }(jQuery));

  25. Zulfiquar rana on July 24, 2013 at 2:36 am said:

    You Have to Improve it

  26. Bijomon Varghese on July 18, 2013 at 7:17 am said:

    Finally understood, how to create a jquery plugin. Great article and nicely described. Hats off to you and your effort.

  27. mrtukkae on July 17, 2013 at 12:44 am said:

    Million Thanks for this Great Helpful blog 😉

  28. Thanks for this article, it is really useful and has helped me to gain new knowledge.

  29. Anand Deep Singh on June 21, 2013 at 6:07 am said:

    very nice way to define the things. I love the way you define

  30. sjmohideen on June 20, 2013 at 7:20 am said:

    Easily to understand . I like that stuff

  31. thanks for the article, it really helped

  32. Ramires on June 12, 2013 at 8:14 am said:

    Good! I just use your tutorial to make my own plugin!
    Cheers from Brazil!

  33. Antony on June 12, 2013 at 3:25 am said:

    That is the best plugin tutorial I’ve ever read. Thanks a whole bunch!!!!

  34. Coder on May 27, 2013 at 9:24 am said:

    very nice and brief

  35. Shivam Chopra on May 26, 2013 at 9:08 am said:

    Nice info

  36. Very nice written step by step info!

  37. Muhammad Asif on May 21, 2013 at 2:31 am said:

    Cool, one more step should’ve been here. How to define and work with functions inside our plugin.

  38. Thank you! Really cool article!

  39. Great walkthrough of the basics of jQuery plugin development. Thanks for the effort.

  40. That is a copy&paste from jQuery website …

  41. Sir, it is great indeed!!!!!

  42. This is really cool – I can’t wait to try it out. Thanks for sharing!

  43. That’s Great 😉

Leave a Reply

You must be logged in to post a comment.

Learn to code with Treehouse

Start your 7 day free trial today and get access to hundreds of video courses in web development, design and business!

Learn more