Create A jQuery Plugin

Learn How to Create a jQuery Plugin

Sep 17th in Screencasts by Jeffrey Way

You might think to yourself, "What is all the fuss with jQuery? You have to download a bunch of plugins to even make the library worth while.". First, that isn't true. Second, the jQuery library was specifically designed for that very purpose. By keeping the core library as small as possible - about 16 kb - users can then apply additional plugins at their own discretion. Today, I'll teach you how to build your first "Center" plugin from scratch. Let's get started!

PG

Author: Jeffrey Way

Hi, I'm Jeff. I'm the editor of Nettuts+, and the Site Manager of Theme Forest. I spend too much time in front of the computer and find myself telling my fiance', "We'll go in 5 minutes!" far too often. I just can't go out to dinner while I'm still producing FireBug errors...drives me crazy. During my free time, I sporadically write articles for my own personal blog. If it will keep you in the good graces of the church, follow us on Twitter.

Our Objective

We want to create a plugin that will dynamically adjust the styling of a specified element in order to keep it vertically and horizontally centered on the page at all times - even when the browser window is resized. Very little is required up front. You only need to make sure that you have the jQuery library downloaded.

The Screencast

Step 1

The first step when creating a plugin is to add a blank Javascript file. Naming conventions state that the file should be named "YourPluginName.jQuery.js". Once you've created this file, make sure that you create a reference to it in your document.

<head>
    <script src="jquery-1.2.6.pack.js" type="text/javascript">
    <script src="center.jQuery.js" type="text/javascript">
</head>

Step 2

Next, paste in the following code.

(function($){

$.fn.center = function(){

var element = this;

$(element).load(function(){

changeCss();

$(window).bind("resize", function(){
    changeCss();
});

function changeCss(){

    var imageHeight = $(element).height();
    var imageWidth = $(element).width();
    var windowWidth = $(window).width();
    var windowHeight = $(window).height();

    $(element).css({
        "position" : "absolute",
        "left" : windowWidth / 2 - imageWidth / 2,
        "top" : windowHeight /2 - imageHeight / 2
    });
};
});

};

})(jQuery);

I go into much greater detail in the video, however, I'd still like to go over a few key points. Any time that you create a plugin, it must be wrapped with:

$.fn.center = function(){};

"Center" should be replaced with whatever your plugin's name is. This lets jQuery know that you're extending its methods. Now, though it does absolutely nothing, we can call our center method with:

$(function(){
  $("#someElement").center();
});

Step 3

You must understand how to manually center an image on a page before creating the plugin. First, your element must be positioned absolutely. Otherwise, it obviously won't budge when we alter the "left" and "top" values. Next, the image needs to be shifted 50% of the browser's width to the left. Finally, in order to compensate for the image's width, we need to subtract one half of the image's width.

function changeCss(){
    var imageHeight = $(element).height();
    var imageWidth = $(element).width();
    var windowWidth = $(window).width();
    var windowHeight = $(window).height();

    $(element).css({
        "position" : "absolute",
        "left" : windowWidth / 2 - imageWidth / 2,
        "top" : windowHeight /2 - imageHeight / 2
    });
  };

This will perfectly place the center of the image in the center of the page. It's a bit hard to explain with text. Be sure to watch the video for a greater explanation.

Step 4

Continuing on, we need to create a listener for when the browser window is resized.

$(window).bind("resize", function(){
    changeCss();
});

"ChangeCss()" is a function that adjusts the left and top values of our image. By calling it again when the window is resized, jQuery will recalulate those values.

You're Done!

If you have any questions, please feel free to leave a comment and I'll make sure that I respond. As always, this might not be "real world ready". What happens if the user has Javascript turned off? And of course, there are some ways to do this using pure CSS - but I digress.

Subscribe to the Weekly Screencasts

You can add our RSS feed to your ITUNES podcasts by doing the following:

  1. Once ITUNES has loaded, clicked the "Advanced Tab"
  2. Choose "Subscribe to Podcast"
  3. Enter "http://feeds.feedburner.com/NETTUTSVideos"

That should do it! The screencast will also be searchable on ITUNES in the next twenty four hours.

  • Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.


Related Posts

Check out some more great tutorials and articles that you might like

Enjoy this Post?

Your vote will help us grow this site and provide even more awesomeness

Plus Members

Source Files, Bonus Tutorials and
More for $9 a month for all TUTS+
sites in one subscription.

Join Now

User Comments

( ADD YOURS )
  1. PG

    Philo September 17th

    Nice Tutorial! :)

    ( Reply )
  2. PG

    Jaswinder Virdee September 17th

    AWESOME! looking forward to many more screencasts, glad to see nettuts is still growing!

    ( Reply )
  3. PG

    Chris Coyier September 17th

    Nice intro Jeffrey! Looking forward to more videos =)

    I’m far from an expert, but I read something in jQuery in Action (pg. 189) that is probably relevant here. They say you should wrap your plugins in a function that passes in the “$” as a parameter, then you are 100% safe to use “$” within your plugin. Otherwise, if the user of the plugin uses $.noConflict(); or otherwise re-defines “$”, it could break your plugin.

    (function($) {
    // Plugin definition
    $.yourFunction = function(params) {
    // Plugin stuff
    }
    })(jQuery);

    ( Reply )
  4. PG

    waqaszahoor September 17th

    WOW! That’s great..

    ( Reply )
  5. PG

    Jeffrey Way September 17th

    @Chris – Very good point. It helps to ensure that jQuery doesn’t conflict with other libraries. I decided not to add that part at that last minute…just to make sure that everyone could understand it. I’m planning on doing a more advanced screencast in the coming weeks that will go over this very thing.

    Great suggestion, though. To everyone reading the comments, Chris is absolutely right. Make sure that you pass in “$”. It’s not required – but is generally considered to be a best practice….and can save you some potential headaches.

    ( Reply )
  6. PG

    hcabbos September 17th

    “Make sure that you pass in “$”. It’s not required – but is generally considered to be a best practice”

    Chris, can’t you just update the tut to show us?

    ( Reply )
  7. PG

    David Tremblay September 17th

    Very nice video. It’s great that you guys are starting to make podcasts ! My minor gripe is that the sound quality is very low you may want to check that in the future (as it can be annoying at times). Looking forward the next ones !

    ( Reply )
  8. PG

    Lamin Barrow September 17th

    PLUGINS RULE. This should be a lesson to any one in software development. Firefox, Wordpress and Jquery are only successful because the creators made them to be extensible. Facebook and Twiter are prime time because they provide an open API. So if you want to make the next big thing always keep these things in mind.
    Nice tut BTW. Thanks.

    ( Reply )
  9. PG

    Jeffrey Way September 17th

    @hcabbos and everyone else – I went ahead and updated the code to help you.

    ( Reply )
  10. PG

    THE MOLITOR September 17th

    Doesn’t work on FireFox 3.0.1 for Mac… Glad to see video tutorials on the site now!

    ( Reply )
  11. PG

    BroOf September 17th

    GREAT!!!! More Screencast vidoes ;D!

    ( Reply )
  12. PG

    span September 17th

    Great tutorial, love the screencast form of tutorials :]

    One small thing that annoys me a bit is the yellow ring following your mouse but that’s just my personal preference.

    Keep up the fantastic work Nettuts team!

    ( Reply )
  13. PG

    Jeffrey Way September 17th

    @Molitor – Are you sure? I just checked Firefox on the Mac and it’s working just fine.

    @span – Yeah, I agree. I’ve been out of town the last few days. So, I had to record this using my laptop. We’ll make sure that the audio quality of next week’s screencasts is much better.

    ( Reply )
  14. PG

    Addison Kowalski September 17th

    Heavens yes! This solves a huge problem I’ve had for the longest time. I was actually asked this question recently at an interview. Now I have the answer.

    ( Reply )
  15. PG

    mark September 17th

    MooTools version – not a plug in, and neither version handles page scrolling, but here it is:

    var x;
    window.addEvents({
    ‘domready’: function(){
    x = func.bind($(’test’));
    x();
    },

    ‘resize’: function(){
    x();
    }
    });

    function func(){
    var window_size = window.getSize();
    var ele_size = this.getSize();

    this.setStyles({
    ‘top’: (window_size.y – ele_size.y) / 2,
    ‘left’: (window_size.x – ele_size.x) / 2
    });
    }

    ( Reply )
  16. PG

    Ben Griffiths September 17th

    Fantastic, the screencast is great :) By the way, I swear your constanly saying netflix, not nettuts ;)

    ( Reply )
  17. PG

    Rich Samuels September 17th

    It’s possible to do this with just CSS though and you don’t get the awkward jerking action whilst the styling updates. Or am I missing something?

    ( Reply )
  18. PG

    ANeuby September 17th

    Whooo, very cool screencast ! Thanks!

    ( Reply )
  19. PG

    bananaman September 17th

    Uah, I never used jQuery, but after seeing that, I’m glad I didn’t. I really don’t get the logic behind this whole stuff, like function-naming etc. MooTools does it a hell of a lot better. Nice tutorial though, I’d like to see more MooTools stuff from you guys.

    ( Reply )
  20. PG

    Dainis Graveris September 17th

    Love to see screencasts! Keep going and I love You doing that! Thanks!

    ( Reply )
  21. PG

    Michael Espinosa September 17th

    That was great! Keep up the good work.

    ( Reply )
  22. PG

    Michael Thompson September 17th

    Great job (necessary fluff) but (meat of my comment) I have a few issues…

    First, plugin naming syntax is not “myplugin.jQuery.js” it’s “jquery.myplugin.js” — almost always in full lowercase. Check the jQuery plugins repository if you’re not certain this is true.

    Second, there’s no need to define “element”. In both contexts of “this” you will be referring to the proper element.

    Third, there isn’t any element iteration or return. If multiple items are selected (say, “$(’p')”) they are not iterated over, and the method chaining jQuery is known for will break because they’re not returned. The entire contents of this plugin inside of “$.fn.center = function() {…}” should be wrapped with “this.each(function() { … }” and at the very end inside of the “each()” iteration should be a “return this;”.

    I understand the desire to make things easy for new plugin authors, but teaching someone just getting started the wrong way to go about things can be a serious problem later on.

    ( Reply )
  23. PG

    Jeffrey Way September 17th

    @Michael – You are right about the naming. I just had a brain freeze. Sorry about that! :)

    Second, I’ve found that assigning “this” to a variable is generally a good practice. When your plugins start becoming more advanced, this almost always becomes a requirement – at least in my case.

    In response to your last criticism, you are correct. But, try to remember that this is a “creating your FIRST plugin” tutorial. If it becomes too complicated, it’ll go over a beginner’s head. This was meant to manipulate a single element. But sure, if you’ll be calling the “center” method from a wrapped set, you should use a for statement.

    No need to get too complicated in this introductory tut. I’ll go into much greater detail in Part 2 of this screencast.

    Thank you very much for your thoughts though. Very good, and true arguments.

    ( Reply )
  24. PG

    Taylor Satula September 17th

    Doesn’t work on google chrome

    ( Reply )
  25. PG

    Jeffrey Way September 17th

    @Taylor – I’m using Chrome right now. I just checked the demo. It works just fine.

    ( Reply )
  26. PG

    Rich Samuels September 17th

    Taylor it works better in chrome than it does in FF3 (PC) as it’s not so jumpy.

    ( Reply )
  27. PG

    Braden Keith September 17th

    I’m liking the vodcast. I heard you mention finding it on iTunes, but I did a search and cant find the feed – nor subscribe obviously. Maybe it hasn’t propagated through their system yet?

    ( Reply )
  28. PG

    Moksha Solutions September 17th

    Hi, Really Very Happy to see you working in Visual Studio2008, i am keeping my finger cross in hope to see some really great asp.net tutorial.

    thanks for sharing this jquery,

    ( Reply )
  29. PG

    Braden Keith September 17th

    My apologies for not seeing that last note on the podcast. Disregard my comment.

    ( Reply )
  30. PG

    Miles Johnson September 17th

    YOU DONT HAVE TO name the javascript jquery.classname.js, it doesnt matter at all, jQuery is just trying to have a standard, who cares.

    Anyways very simple and straight forward, ive written a couple myself.

    ( Reply )
  31. PG

    Man Mohan Singh September 17th

    Nice Tutorial………..
    …………….. Great Job
    Keep it up…………….

    ( Reply )
  32. PG

    insic September 17th

    nice to hear that nettuts having screen cast. and great tutorial too.

    ( Reply )
  33. PG

    mattems September 17th

    im so undecided between jquery and mootools.

    Need a good comparison article.

    thanks for sharing this, very useful!!

    ( Reply )
  34. PG

    Rakibul Islam September 17th

    Thanks for the tutorial, i was looking a tutorial like this for starting JQuery from the scratch.

    ( Reply )
  35. PG

    Stefan September 17th

    Nice tutorial! I like it :D

    ( Reply )
  36. PG

    Shane September 18th

    Some good points made along the way Jeffrey. I’ve written a few jQuery plugins for a project that I’m currently working on, and find the simplicity of using them a real joy, and makes their development really fun.

    This is a good, simple example of how to create a plugin. Thanks for posting.

    ( Reply )
  37. PG

    James September 18th

    Nice video Jeffrey!

    If this is going to become a weekly occurance can we spruce it up a bit? How about a really nice mic like Chris’ -> http://css-tricks.com/screencasting-setup/

    ( Reply )
  38. PG

    Jeffrey Way September 18th

    @James – Definitely. I’ll be investing in a nice condenser mic sometime this week.

    ( Reply )
  39. PG

    Dan September 18th

    Thank you sir, may I have another?

    ( Reply )
  40. PG

    Windows Themes September 18th

    I really like this website because I am learning a lot`s of things. Thanks for posting Jeffrey !

    ( Reply )
  41. PG

    Darin September 18th

    While I really like jQuery and am working to include it in my designs, I think we should use it for things that (X)HTML/CSS can’t do. This is actually quite easily done in CSS and as someone else pointed out – it works smoother (not to mention much smaller page size).

    For those wondering how to do this in CSS:
    Basically, you absolutely position the image with top: 50%; and left: 50%.
    Then apply a negative margin to the top that is 1/2 the height of the object and a negative margin to the left that is 1/2 the width. Done.

    ( Reply )
  42. PG

    Michael Espinosa September 18th

    @JeffreyWay I am trying to use this plugin with a div instead of an image. It does not seem to be working though. I changed the code to $(’#divId’).center(); and then in the jQuery.center.js I changed it to

    $(element).css({
    “position” : “absolute”,
    “left” : windowWidth / 2 – 375,
    “top” : windowHeight / 2 – 255

    Because I know the size of the div will not be changing.

    Thanks for any help.

    ( Reply )
  43. PG

    Jeffrey Way September 18th

    Hey Michael. Remove the “$(element).load(function();” wrap. In the case of this div, there isn’t anything to load. Remove it (and the closing brackets) and it will work just fine on a div element.

    Hope this helps!

    ( Reply )
  44. PG

    Michael Espinosa September 18th

    @JeffreyWay Thanks worked great!

    ( Reply )
  45. PG

    Miles Johnson September 18th

    @mattems – Its simple. jQuery = functionality, Mootools = animations.

    @Darin – THis is true, but I think he just wanted to show off HOW TO make a plugin… not this actual plugin itself. I dont think its necessary to write a full blown plugin, this is fine.

    ( Reply )
  46. PG

    Tim September 19th

    Let’s try…

    ( Reply )
  47. PG

    Kidd Lee September 19th

    Hi Jefferey,

    I try to apply on div, but just couldn’t get it work…

    my html is:

    Hello

    jQuery.center.js is:

    (function($){

    $.fn.center = function(){

    var element = this;

    function(){

    changeCss();

    $(window).bind(”resize”, function(){
    changeCss();
    };

    function changeCss(){

    var imageHeight = $(element).height();
    var imageWidth = $(element).width();
    var windowWidth = $(window).width();
    var windowHeight = $(window).height();

    $(element).css({
    “position” : “absolute”,
    “left” : windowWidth / 2 – imageWidth / 2,
    “top” : windowHeight /2 – imageHeight / 2
    });
    };
    });

    };

    })(jQuery);

    Have i done anything wrong?

    ( Reply )
  48. PG

    Evan September 19th

    Since I see some mootools comparison in here I will post an example of how I would do this with mootools. In this case I would probably just implement some more functionality on to Element but you could also write a class to do it.

    You can pin and unpin any element using the following syntax.
    $(’some-element’).pinCenter();
    $(’some-element’).unPinCenter();

    Element.implement({
    pinCenter: function(){
    this.setStyle(’position’, ‘absolute’);
    this.center();
    this.pinEvent = window.addEvent(’resize’, this.center.bind(this));
    },
    unPinCenter: function(){
    this.setStyle(’position’, ’static’);
    this.removeEvent(this.pinEvent);
    },
    center: function(){
    var windowSize = window.getSize();
    this.setStyles({
    top: (windowSize.y / 2) – (this.offsetHeight / 2),
    left: (windowSize.x / 2) – (this.offsetHeight / 2)
    });
    }
    });

    ( Reply )
  49. PG

    Mark September 19th

    Evan I like your implementation. You’ve given all of the elements (that go through mootools selection) the ability to be centered in the page, good stuff.

    you have an error in your left calculation though, you’re using offsetHeight

    ( Reply )
  50. PG

    THE MOLITOR September 21st

    I tested this on my other mac and it’s working now. Awesome!

    ( Reply )
  51. PG

    Kidd Lee September 22nd

    Can anyone please show me a working example of how to get this done in DIV? thanks a lot!

    ( Reply )
  52. PG

    John September 24th

    Is there’s a DIV sample using this tutorial? I think this is VERY USEFUL if we can make it using DIV.

    ( Reply )
  53. PG

    Yosi September 26th

    I can’t see the video,
    When I start the video I see the video of the jFlow Plugin and not how to create a plugin.

    ( Reply )
  54. PG

    playinlife December 13th

    I can’t see the video too…

    ( Reply )
  55. PG

    Nora Brown January 25th

    Confused…if “this” is already a jQuery object, and you then assign that object to the variable “element”, why do you need to wrap it as in “var imageHeight = $(element).height();” ? Why not just element.height(), which does seem to work at least in Safari and Firefox?

    ( Reply )
  56. PG

    jQuery Lover January 30th

    @Nora:
    Because “this” is a DOM object and $(this) or $(element) is a jQuery object and this object has height() method in it.

    You can read more about jQuery custom functions and custom plugins here.

    You might find this useful as well. All jQuery plugins related posts: http://jquery-howto.blogspot.com/search/label/plugin

    ( Reply )
  57. PG

    Sam June 16th

    I am not able to see this video

    ( Reply )
  58. PG

    calyan Kumar June 17th

    hey! that stuff was really helpful. I have developed a sample plugin. Now where can i make it available to others?

    ( Reply )
  59. PG

    Mark September 17th

    Ok so this is pretty cool, a nice example of how to create a plugin.

    However, the functionality of this is useful to me. How can I adapt this to center the image within a div, not the browser window?

    The div will be a set width/height and the image within it will vary in size but need to stay centered..?

    There is examples out there in google but appear to be quite clunky..

    Many thanks

    ( Reply )
  60. PG

    Eyveneena November 17th

    I have been studying jQuery for about two years now and I was to the point whenever rewriting a set of code that I usually use became tedious I thought “maybe it is time to learn how to turn this into a function?” I ran across this tutorial creating a plugin. Plugins are for the “pros”. This was explained and I realized that I understood more than I thought I would about a basic plugin. So, I will attempt to make a plugin. Anyway, this was truely enlightening to the core idea of creating a plugin. Not sure what I am getting into. LOL
    Thank you.

    PS. are you using sql software to create this?

    ( Reply )
  61. PG

    Eyveneena November 17th

    I did it! I did it! I did it! I built my first plugin! It works OMGoodness!
    Thank you soooo much for this tutorial! And I used Visual Web Developer to do it!

    ( Reply )
  1. Arrow
    Gravatar

    Your Name
    November 17th