ATTENTION ATTENTION
gear.huuah.com has launched. Visit the shop at http://gear.huuah.com/. Lots of Photo Gear at the moment
ATTENTION ATTENTION
Itsplanned.com is just launched! - Task and project management made easy. Try it for free.

Create your own lists of things to do - arrange the order to do them - move them around - group them

No limitations - all free project management - try the free demo before signing up - demo: itsplanned.com
Howto make a jQuery menu plugin
28.07.2009

If you want to reuse your jQuery code, it can be a good idea to make the code into a jQuery Plugin. This makes it easier to use on different elements or even to distribute it.

Demonstration:
I have made a small simple 1 level menu for this demonstration. If you hover you mouse on Menu 1 or Menu 3 you will see a submenu sliding down. Menu 2 has no submenu and will therefor display nothing.

How: The HTML
The HTML is pretty much a standard list like this:

<ul id="nav">
    <li><a href="#">Menu 1</a>
        <ul>
            <li><a href="#">Menu 1.1</a></li>
            <li><a href="#">Menu 1.2</a></li>
            <li><a href="#">Menu 1.3</a></li>
        </ul>
    </li>
    <li><a href="#">Menu 2</a>
    </li>
    <li><a href="#">Menu 3</a>
        <ul>
            <li><a href="#">Menu 3.1</a></li>
            <li><a href="#">Menu 3.2</a></li>
            <li><a href="#">Menu 3.3</a></li>
        </ul>
    </li>
</ul>

How: The basic of a plugin
The very basic setup for a jQuery Plugin is the following couple of lines, where I am creating a function called menu(), which can be called on an element.:

(function($) {
    $.fn.menu = function() {
        ... javascript code goes here...
    }
})(jQuery);

To activate the plugin, you will have to call the menu() function on an element, which can be done like this:

$(document).ready(function() {
   $().ready(function() {
        $('#nav').menu();
   });
});

The plugin has now been activated and the code within the function will be run on the #nav element.

How: Making the plugin do something
This plugin is going to make a submenu slide down when the parent element is being hovered by the mouse. I will not go into details of the code other than the comments I have made below:

(function($) {
    $.fn.menu = function() {
        // make sure there is a <ul>-submenu. If not - it will fail
        $(this).children("li").append('<ul></ul>');
        // add classes to the <li> and <ul>
        $(this).children("li").addClass("mmmenu");
        $(this).contents().find("ul").addClass("mmsub");

        // ready-state to prevent looping
        var ready = true;
        // when hover do this
        $("li.mmmenu").mouseenter(function() {
            // if plugin is ready, then continue
            if ( $(this).children("ul.mmsub").is(':visible') == false && ready == true ) {
                ready = false;
                // hide all submenus
                $("ul.mmsub").hide();
                // display the selected submenu
                $(this).children("ul.mmsub").slideDown(500, function() {
                    ready = true;
                });
            }
        });
    }
})(jQuery);

How: Passing options to the plugin
The above code will slide down the submenu at a speed of 500ms. But what if I would like to override this value? Lets add some options to the code as well:

(function($) {
    $.fn.menu = function(options) {
        var defaults = {
            speed: 500,
        }; 

        var options = $.extend(defaults, options);
        ...
                $(this).children("ul.mmsub").slideDown(options.speed, function() {
                    ready = true;
                });
        ...
    }
})(jQuery);

The code now support options. There is a default option, where speed is set to 500ms. and the slideDown-function is now using the options-variable.

To set the slide down speed to ie. 2000ms, then pass the option like this:

$(document).ready(function() {
   $().ready(function() {
        $('#nav').menu({speed: 2000,});
   });
});

There you go. If you would like to download the mmmenu-plugin, just click here.

Leave a Reply