SOLAERAWEBDESIGN

NEWS AND IDEAS

How to Write a Basic Dropdown Menu in JQuery

Recently for a project for a friend, I needed some dropdown menus in a horizontal bar which would appear by a slideDown animation when the mouse hovered over them. Since most of the code snippets I found on the subject appeared on mouse click rather than on mouse hover and would need some tweaking anyway, I decided to go ahead and try to write my own version, which I now present here for anyone who wants to use it.

<!-- MARKUP -->
<div id="menu">
<ul class="level1">
<li id="home"><a href="#">HOME</a></li>
<li id="news"><a href="#">NEWS</a></li>
<li id="html"><a class="has_drop" href="#">HTML</a>
	<ul class="level2">
	<li><a href="#">HEADINGS</a></li>
	<li><a href="#">PARAGRAPHS</a></li>
	<li><a href="#">IMAGES</a></li>
	<li><a href="#">ANCHORS</a></li>
	</ul></li>
<li id="css"><a class="has_drop" href="#">CSS</a>
	<ul class="level2">
	<li><a href="#">SELECTORS</a></li>
	<li><a href="#">PROPERTIES</a></li>
	<li><a href="#">STYLESHEETS</a></li>
	</ul></li>
<li id="javascript"><a class="has_drop" href="#">JAVASCRIPT</a>
	<ul class="level2">
	<li><a href="#">JQUERY</a></li>
	<li><a href="#">FUNCTIONS</a></li>
	</ul></li></ul>

</div><!-- END MENU -->
 /* ========= STYLING ============ */
#menu { height: 44px; background: #03134e; }
#menu ul { list-style: none; font-family: Arial; }
ul.level1 li { float: left; margin: 4px 0 0 0; height: 35px; position: relative; }
ul.level1 li a { padding: 11px 43px 0; color: #fff; display: block; height: 27px; text-decoration: none; float: left; }
ul.level1 li a:hover { background: #f9a01b; }
ul.level2 { position: absolute; left: 0; top: 38px; background: #010724; margin: 0; padding: 0; display: none; float: left; width: 170px; border: 1px solid #03134e; border-bottom: none; }
#html .level2, #html .level2 a { width: 128px; }
#css .level2, #css .level2 a {width: 118px; }
#javascript .level2, #javascript .level2 a {width: 180px; }
ul.level2 li { border-bottom: 1px solid #03134e; margin: 0; padding: 0; }
ul.level2 li a { text-align: center; padding: 0; margin: 0;	height: 25px; padding-top: 10px; }
ul.level2 li a:hover { background: #f9a01b; }
// *************** SCRIPTING ******************

$(document).ready(function(){  

	//runs dropdowns on hover
	$('ul.level1 li').hover(function() {
         $(this).children('ul.level2').slideDown('medium');
	}, function() {
		$(this).children('ul.level2').slideUp('medium');
	});

	//when submenus are hovered over, top li remains lit
	$('ul.level2').hover(function() {
         $(this).parent('li').find("a.has_drop").css('background', '#010724');
	}, function() {
		$(this).parent('li').find("a.has_drop").css('background', '');
	});

	//ul level1 links with level2 do not go anywhere
	$('a.has_drop').click(function(e) {
		e.preventDefault();
		})
		.hover(function() {
				$(this).css('cursor', 'default');
				},
				 {

		});
});

Not particularly complicated, so let’s see what’s going on here.

As always, the first level is the markup. It’s a basic unordered list with an ID, a set of “level1″ list items, also with id’s, and some “level2″ lists nested within. This is then styled into a horizontal menu bar with some color and appropriate hover behaviors, and the level 2 lists are absolutely positioned beneath their parent list and hidden initially when the page loads.

Now, for the meat of it — the JQuery…

//runs dropdowns on hover
	$('ul.level1 li').hover(function() {
         $(this).children('ul.level2').slideDown('medium');
	}, function() {
		$(this).children('ul.level2').slideUp('medium');
	});

On document ready, the first thing we do is set the dropdowns behavior to run when the first level list items are hovered over. Using the JQuery selector syntax, we identify all LI children of level1 ULs, and then use the hover method to force any submenus to slideDown (become visible) on mouseover and slideUp (become hidden) on mouseout. Needless to say, if the LI does not have a submenu with the appropriate class, the function will do nothing.

//when submenus are hovered over, top li remains lit
	$('ul.level2').hover(function() {
         $(this).parent('li').find("a.has_drop").css('background', '#010724');
	}, function() {
		$(this).parent('li').find("a.has_drop").css('background', '');
	});

From the CSS we already have our links changing color when the mouse hovers over them. However, we might want our level1 LI elements to remain changed when our mouse is on the submenus. This is accomplished via a chain of JQuery commands, first to ID that the mouse is on the submenu — $(‘ul.level2′) and, later, $(this) — then to its parent LI — $(this).parent(‘li’) — then to the link within that LI which has the class “has_drop” — $(this).parent(‘li’).find(‘a.has_drop’) . This last bit is necessary because a simple .find(‘a’) would identify all of the links which are children of the LI in question, which would also include those in the dropdown itself.

//ul level1 links with level2 do not go anywhere
	$('a.has_drop').click(function(e) {
		e.preventDefault();
		})
		.hover(function() {
				$(this).css('cursor', 'default');
				},
				 {

		});

This part more relates to accessibility than anything else. It is potentially possible that someone might view your site without Javascript enabled — if this were the case, the dropdown menus would be impossible to see. Thus, within the markup, the LIs with dropdowns also contain a link (with the class “has_drop”) which could take the user perhaps to a menu where they could view the options. In the case in which I was using this, I didn’t want to spend too much time on that menu page, so I wanted it only for the people who didn’t have JS enabled; thus, as part of my JQuery code, I disable those links which have that class via the “preventDefault()” method, then cause the cursor not to show a pointer (further discouraging distracting clicks) when those links are hovered over.

And that’s that! Easily styled further and pretty simple in its behavior. Suited my needs and will hopefully be useful to you as well.

Click here to view an example of what the code above produces.

If you have any improvements, spot any errors or points of difficulty, or just want to add something to the discussion, please leave a comment — I’d love to hear from you!

One Response to “How to Write a Basic Dropdown Menu in JQuery”

  1. ahab says:

    Nice! Works well in FF 3.5, Opera, even IE 6. Thanks for the code.

Leave a Reply