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