Sliding menu using jQuery

Time for round #2! This time we’ll be building a sleek menu using jquery and some styles. What’s beautiful about jquery is how you can change a few bits and you get an entirely new effect. Last time we built some rollovers and tooltips using jquery and this time we’ll be building our slide menu on top of the same code. This tutorial assumes that you have a basic knowledge of jquery. Before we start, you might want to go ahead and try our example of sliding menus using jquery.

UPDATE: July 20. I’ve just posted a new version of the sliding menu, with image preloading and full block clickable.

The markup

This is exactly the same than before, but for the newcomers here it goes again:

[code language=”html”]
<ul id="iconbar">
<li><a href="#">
<img src="key.gif" alt="" />
<span>Change your password</span>
</a></li>
<li><a href="http://feeds.feedburner.com/ilovecolors&quot; target="_blank">
<img src="rss.gif" alt="" />
<span>Suscribe to our RSS!</span>
</a></li>
<li><a href="#">
<img src="sel.gif" alt="" />
<span>Choose your options!</span>
</a></li>
</ul>
[/code]

As you can see is just a row of li’s with an anchor and two blocks inside it: an image, who triggers the hover event, and a span that is revealed when the event launches.

The idea here is to horizontally expand the li width, thus revealing the hidden span that at the same time will be animated in opacity fading in.

The styling

Basic as it is, it’s all we need.

[code language=”css”]

#iconbar li            {
float:left; position:relative; margin-right:20px;
padding: 10px 5px 5px 10px;
width: 30px;
background:#eef;
border: 1px dashed #ffc0ff;
}
#iconbar span    {
width: 100px;
height: 35px;
position: absolute;
padding: 0px 5px 5px;
display: none;
line-height:110%;
color:#409BED;
}

[/code]

I’ve added a background and a dashed border to the li element to show you that the event is triggered when are over the image and not over the li. We still need the absolute positiong of the span, which is relative to the ul element through the li element.

The code

Now that our elements are positioned we need to add some action to them!

[code language=”js”]

jQuery(document).ready(function(){
$("#iconbar li img").hover(
function(){
var iconName = $(this).attr("src");
var origen = iconName.split(".")[0];
$(this).attr({src: "" + origen + "o.gif"});

$(this).parent().parent().animate({ width: "140px" }, {queue:false, duration:"normal"} );
$(this).parent().parent().find("span").animate({opacity: "show"}, "fast");
},
function(){
var iconName = $(this).attr("src");
var origen = iconName.split("o.")[0];
$(this).attr({src: "" + origen + ".gif"});

$(this).parent().parent().animate({ width: "30px" }, {queue:false, duration:"normal"} );
$(this).parent().parent().find("span").animate({opacity: "hide"}, "fast");
});
});

[/code]

Right after the DOM is ready() we target the img element within each li element of our navigation bar.

[code language=”js”]

$("#iconbar li img").hover(

[/code]

and we pass the parameters (two functions in fact) that it needs: what to do when the mouse is over the image and what to do when the mouse leaves the image.

[code language=”js”]

function(){

//when the mouse is over the image…

}

,    //notice the comma separating the two members…

function(){

//when the mouse leaves the image…

}

[/code]

Now, when the mouse is over the image we need that the <li>, which is the parent of <a>, parent of <img>, expands its width to 140px.

[code language=”js”]

$(this).parent().parent().animate({ width: "140px" }, {queue:false, duration:"normal"} );
$(this).parent().parent().find("span").animate({opacity: "show"}, "fast");

[/code]

We’re using the animate function to smoothly increase the size (instead of a blocky jump), and of course, we pass as a parameter the desired width. The other parameters are equally important, and is queue:false what puts together everything. Suppose that you fastly move your mouse over the items. Since jQuery enqueues animations, and the animations we set are based on the $(this) element, jQuery will try to play all the animations which will likely cause a collision between two or more animations that jQuery tries to play. Enter the queue:false parameter. This will force jQuery to start the animation of the other items even if the last animation of the previous item hasn’t been completed.

Finally, in order to restore our item to its previous state, before the animation happened, we use

[code language=”js”]

$(this).parent().parent().animate({ width: "30px" }, {queue:false, duration:"normal"} );
$(this).parent().parent().find("span").animate({opacity: "hide"}, "fast");

[/code]

This will restore the original width attribute that is the same to the defined previously in the stylesheet and will hide or span tag.

So there you have it, your own menu with sliding items. If you haven’t, make sure you read the previous article on creating rollovers and tooltips using jquery and stay tuned for more! see you next time!

72 thoughts on “Sliding menu using jQuery”

  1. Great Post , but i have an idea what about making the whole block when expands clickable instead of the icon only.

  2. I agree – what about having the whole block trigger the button to expand rather than just the icon?

  3. Very nice menu! Is there anyway to ‘preload’ it as it isn’t functioning properly in Opera 10 but does after you sit on the icon -> hover away -> hover back on the icon.

    Great work!

    1. I’ve updated the example. It should be working fine now, I’m testing it in Opera 10 and I’ve seen the issue Corey commented about. I’ve added an image preload and it seems to be working fine. This is what I’ve added at the top of the script.
      jQuery.preloadImages = function()
      {
      for(var i = 0; i<arguments.length; i++)
      jQuery("”).attr(“src”, arguments[i]);
      }
      jQuery.preloadImages(“key.gif”);
      jQuery.preloadImages(“keyo.gif”);
      jQuery.preloadImages(“rss.gif”);
      jQuery.preloadImages(“rsso.gif”);
      jQuery.preloadImages(“sel.gif”);
      jQuery.preloadImages(“selo.gif”);
      I will post later a revision of the menu including full block clicking.

    1. Lam, that is hardly simpler. You’re loading two libraries in addition to jQuery library and adding a script.

  4. А что Вы скажете, если я возьму на себя смелость утверждать, что все Ваши посты, не более чем выдумка автора?

  5. is there a way you could specify one to stay open if the mouse isn’t on any of the items (eg like a current page indication)?

Leave a Reply to Connor Cancel reply