Learning jQuery: Your First jQuery Plugin, "BubbleUP"

written by aext on February 22, 2010 in Javascript and Popular with 106 comments

Update: The icons used in this tutorial can be found free here.

There are many posts available detailing how to write your own jQuery plugin. It won’t take long before you realize that building in jQuery is very simple. Continuing in our jQuery Learning Series, here we’re going to build your first jQuery plugin. It’ll generate a bubble effect for your menu list and we’re going to call it BubbleUP.

What is BubbleUP? BubbleUP is a fun and easy plugin to get you started in jQuery. The effect is a nice starting point for learning the basics and many of the steps involved in creating other more intricate plugins you will make in the future. With this plugin, images in a list will enlarge with a smooth animation when you move your mouse over it. Then, if you move the mouse out, it will reset to the original size with the same smooth animation.

Implement jQuery

This is a plugin for jQuery, so we first have to implement the jQuery library in our webpage header (you must upload jQuery to your server or link to Google’s hosted version):

<script type="text/javascript"src="js/jquery-1.3.2.js"></script>

1. Choose a name

We will name this plugin as BubbleUP, but feel free to choose another name that suits you better.

In building a jQuery plugin, it’s recommended you write all the plugin code in one javascript file. Your jQuery plugin’s file should be named as: [Your-jQuey-Plugin-Name].jQuery.js, but if it’s too complicated for you, just name it as: bubbleup.js.

Now, we’ll start with a blank javascript file and begin with the following lines (the template for any jQuery plugin):

(function($){
    $.fn.BubbleUP = function() {

        return this.each(function() {

        });

    };
})(jQuery);

We named the plugin above “BubbleUP“, so we are going to define the name of this plugin by using this code:

...

    $.fn.BubbleUP = function() {

...

Because we have more than one item in our list, we have to use the each() function to execute the called function for every item in our list.

The first step is finished: creating the jQuery plugin template and naming it.

2. Implement jQuery Plugin to web page

Now you need to link the javascript file that you created above into your web page. For this, we’ll use this code:

<script type="text/javascript"src="js/bubbleup.jquery.js"></script>

To make the plugin work, we need to use this code below. You can insert it anywhere you want as long as it’s inside the <head> or <body> tags:

<script type="text/javascript">

$(function(){

    $("ul#menu li img").bubbleup();

});

</script>

As you can see in the demo, we are going to enlarge the image in the list. That’s why we use images in this menu as target elements.

3. Animate

Let’s write the skeleton of the code. We’re going to use the mouseover(), mouseout(), animate(), and stop() functions.

(function($){
    $.fn.bubbleup = function() {

        return this.each(function() {

            $(this).mouseover(

                function() {

                    $(this).stop();
                    $(this).animate({

                        ...

                    });
                }

            ).mouseout(

                function() {
                    $(this).stop();
                    $(this).animate({

                        ...

                    });
                }

            );

        });

    };
})(jQuery);

This code basically says this: “Upon mouseover or mouseout, stop any animations that are currently active in this element, and start a new animation (which we’re going to define later)”. We need to immediately stop active animations first to prevent undesirable behavior. This function stop() will stop the animation before it starts the new animation. The function we are using to generate the smooth bubble effect is animate().

4. Build the menu

We need to build the menu using HTML. The menu is an unordered list, so it should be something like below. Notice this list has been simplified for this tutorial.

<ul id="menu">
  <li>
    <a href="#"title="Full RSS Feed">
        <img src="images/rss.png"alt="Full RSS Feed">
    </a>
  </li>
  <li>
    <a href="#"title="E-Mail Delivery">
        <img src="images/email.png"alt="E-Mail Delivery">
    </a>
  </li>
  <li>
    <a href="#"title="Follow me on Twitter">
        <img src="images/twitter.png"alt="Follow me on Twitter">
    </a>
  </li>
  <li>
    <a href="#"title="I'm on FaceBook">
        <img src="images/facebook.png"alt="I'm on FaceBook">
    </a>
  </li>
  <li>
    <a href="#"title="E-Mail Delivery">
        <img src="delicious.png"alt="Save it!">
    </a>
  </li>
  <li>
    <a href="#"title="E-Mail Delivery">
        <img src="images/technorati.png"alt="Favorite this blog">
    </a>
  </li>
</ul>

This HTML code is very simple. You need to create just one image for each item and the jQuery plugin will do the rest. The next step is the CSS.

5. Style the menu (CSS)

The following CSS is used to style the menu. There are two important things that you should notice: position for <li> elements must be set to relative because img elements inside it must be set as absolute. Absolute positioning for an element will not work if the parent is not set as absolute or relative.

The original size of the images is 48px in this tutorial, and the size when enlarged is 96px. That means the images will start animation at 48px and enlarge to 96px. Some margins and padding is in this css code below just make the list display better.

ul#menu {
    margin: 5px 0px;
}

ul#menu li {
    padding: 0px;
    display: inline-block;
    *display: inline; /* IE 7 and below */
    position: relative;
    margin-left: 5px;
    margin-right: 5px;
    width: 48px;
    height: 48px;
}

ul#menu li img {
    width: 48px;
    position: absolute;
    top: 0px;
    left: 0px;
    padding: 0px;
    margin: 0 8px 0 0;
    border: none;
}

6. Create the animations

This is the main part of this plugin. We will pass some parameters to the animate function.

First, I strongly recommended you re-read one of our previous articles,Bubble Effect with CSS. When you return to this post, you will understand why we need to enlarge the image and move it up and left the way we are.

bubble-jquery

As you can see, we need to re-size the images in menu to make it larger. The original size is 48px; the animate function will re-size it to 96px. Take a look in detail at the javascript code below:

(function($){
    $.fn.bubbleup = function() {

        return this.each(function() {

            $(this).mouseover(

                function() {

                    $(this).stop();
                    $(this).animate({
                        left: "-=24",
                        top: "-=24",
                        width: 96
                    }, 'fast');
                }

            ).mouseout(

                ...

            );

        });

    };
})(jQuery);

We will place this image by using negative pixel amounts. The code above will listen for a mousehover() event. When the mouse is over the item, the item will be moved diagonally towards to the top left corner by 24 pixels and then also enlarged to 96px.

However, we have a few issues right here. The problem is the action for this image will cover the image next in the list. Thus, we need to set z-index for it by using css. We also need to reset the placements of all the images before and after the animation, because if the animation is not completed and we move the mouse out and over again immediately, the image will be moved once again diagonally towards the top left corner. We must understand that the amount of pixel this image animates base on the current position + (-24px)

The complete javascript code that helps the animation to work correctly:

(function($){
    $.fn.bubbleup = function() {

        return this.each(function() {

            $(this).mouseover(

                function() {

                    $(this).stop();
                    $(this).css({'z-index' : 100, 'top' : 0, 'left' : 0, 'width' : 48}).animate({
                        left: "-=24",
                        top: "-=24",
                        width: 96
                    }, 'fast');
                }

            ).mouseout(

                ...

            );

        });

    };
})(jQuery);

We do something similar with the mouseout() event, but it has a few differences. Of course, the images must be placed back to the original position and re-sized back to the initial size. However, we need to call a new function when the animation is completed. The callback function is used to reset the z-index to the original.

(function($){
    $.fn.bubbleup = function() {

        return this.each(function() {

            $(this).mouseover(

                ...

            ).mouseout(

                function() {
                    $(this).stop();
                    $(this).animate({
                        left: 0,
                        top: 0,
                        width: 48
                    }, 'fast', function() {
                            $(this).css({'z-index' : 0});
                        }
                    );
                }

            );

        });

    };
})(jQuery);

7. Add option(s)

I know there some great tutorials out there help you make a jQuery Plugin with options supported, but this one is different. The difference is not the content, because there are many ways to add options to it, it’s just a change of the code format. The difference here is in the value of this plugin – it is not just a tutorial, but is actually useful.

In this part, I will help you add options for your menu BubbleUp. So, stop right here and think about the options we might require. How about the tooltip? We can add the tooltip for this over the top of each item when the mouse is hovering over it. Let’s begin!

First, write a draft for it, as a template. jQuery plugins should have default options and users will decide to use these options or not. Change the code to this template:

(function($){
    $.fn.bubbleup = function(options) {

        //Extend the default options of plugin         var opts = $.extend({}, $.fn.bubbleup.defaults, options);

        //Initial the tooltip         var tip = null;

        return this.each(function() {   

            //Set the option value passed here             var $tooltip = opts.tooltip;

            $(this).mouseover(

                function() {

                    if($tooltip) {

                        //Display the tooltip                         
                    }               

                    $(this).stop();
                    $(this).css({
                        'z-index' : 100,
                        'top' : 0,
                        'left' : 0,
                        'width' : 48
                    }).animate({
                        left: "-=24",
                        top: "-=24",
                        width: 96
                    }, 'fast');

                }

            ).mouseout(

                function() {

                    if($tooltip) {

                        //Hide the tooltip                         
                    }           

                    $(this).stop();
                    $(this).animate({
                        left: 0,
                        top: 0,
                        width: 48
                    }, 'fast', function() {
                            $(this).css({'z-index' : 0});
                        }
                    );
                }

            );

        });

    };

    //All default options go here     //Must called     $.fn.bubbleup.defaults = {
        tooltip: false
    }

})(jQuery);

When you mouse-over

This tooltip will display in the same way as other plugins. When you mouse-over, the tooltip will show up and when the mouse is moved away, the tooltip will be invisible.

Add this code to the mouseover() code block and inside the tooltip is this enabled condition:

if($tooltip) {

    tip = $('<div>' + $(this).attr('alt') + '</div>');

    tip.css({
        color: '#333333',
        fontSize: 12,
        fontWeight: 'bold',
        position: 'absolute',
        zIndex: 100000
    });

    tip.remove().css({
        top: 0, left: 0,
        visibility: 'hidden',
        display: 'block'
    }).appendTo(document.body);

  ...

}

We will not use any external CSS, but instead style the tooltip with JavaScript. This code will create a new tooltip which uses the value of the image’s alt attribute. We put it in the div tag to display, then put the tip at the end of the HTML document.

Next, we will display the tip:

if($tooltip) {

  ...

    //Get the width and height of current image item     var position = $.extend({}, $(this).offset(), {
        width: this.offsetWidth,
        height: this.offsetHeight
    });

    //Get the width and height of the tip element                        var tipWidth = tip[0].offsetWidth,
        tipHeight = tip[0].offsetHeight;

    //Set position for the tip to display correctly     //Postion: top and center of image             tip.stop().css({
        top: position.top - tipHeight,
        left: position.left + position.width / 2 - tipWidth / 2,
        visibility: 'visible'
    });

}

However, our image will scale from small size to big size when we mouse-over. If the tip won’t move together with the image, then one of them will be covered by the other. The one that would be covered is the one that has the lower value of z-index.

That’s why we need to animate the tip:

if($tooltip) {

  ...

   tip.animate({
       top: "-=24",
   }, 'fast');

}

When the mouse is away

When the mouse is away, the code is very simple. We just need make the tip visible. However, we should remove it then create and create another one when the mouse is over it again. That’s better than just setting it to be invisible.

if($tooltip) {
    tip.remove();
}

You’re done!

That’s all you need to make a jQuery plugin!

Please understand that this is just a basic version of BubbleUP and it still has some issues. If we are going to create a complete jQuery plugin, we should do more. Creating a jQuery plugin by yourself is very easy if you know the basics of jQuery, and it is easier if you are creating a practical plugin, like BubbleUP, to understand the steps.

Are you going to use it on your site? It is quite a smooth and simple menu, isn’t it? Tell us how you’re using it on your website in the comments and don’t forget to subscribe to the feed!