blenderNetwork patreon blender-logos d heart user th book photo pencil map-marker chevron-right comment comments twitter facebook rss chain navicon google-plus envelope linkedin calendar-o tumblr reddit stumbleupon share-alt blogger flattr flag

Slideout Menus: The jQuery

Blender 3d article

Since we have gotten out menu set up and working for us, we can move on to adding in the jQuery. The jQuery to make this work is very simple and it is quite easy to change the basic animation. All we really need to do is use jQuery to start an animation when we hover over the menu item. There are tons of different things you can do in terms of animation, however I will just show you one. You should be able to figure out the others by using the documentation over at the jQuery website.

Before I start, I am going to assume you know where to put the javascript/jQuery code and how to link the jQuery file to your page and all that. So, first we want to use the ready function for our jQuery:

$(document).ready(function(){

});

If you don\'t know already, this is the function that will be called when the page finished loading (excluding the page content, but thats not important for this tutorial). All of our coding will go inside this function. The next thing we want to do is create the function for when the mouse is hovering over the menu item. The great thing about jQuery is that you can easily pick out any element on the page the same way you would with CSS. So, within the ready function we are going to insert bit of code:

$(\".menu_item\").hover(

);

As you can see, we just created an event that activates when we hover over the named element, our menu_item class. Basically, when you hover over an element with the menu_item class, everything within the hover parentesis is going to run. With that said, we can plug in some more code:

$(\".menu_item\").hover(function(){
$(\".submenu\", this).slideDown(500);
},function(){
$(\".submenu\", this).slideUp(500);
});

The first function is what happens when the mouse goes onto the element and the second one is what happens when you take it off of the element. As you can see, when our mouse goes over a .menu_item the slideDown function will be called, causing the submenu to appear. When we tell the jQuery which element to slideDown we use this coding: \"\".submenu\", this\". Using the \"this\" keyword after naming the element we want to use (.submenu) tells the jQuery that we only want to use the element that is within the element we are hovering over, rather than animating all elements with that class name. In plain English, we want to animate \"this\" submenu and not all of them. This is only really relevant when you have more than one menu item. And, as you can see, the second function is almost exactly the same except that it is sliding the submenu back up to it\'s hidden position.

While this is exactly what we are looking for, there is still a small problem. We initially built the menu with CSS only, so the submenu already has a height given to it. Since the height is not zero, the slideDown animation will not run , instead it will just appear (at least on the first hover). So, what we need to do is set the submenu to a height of zero so that it will work right the first time and then every time after that. I will do this with a preemptive slideUp function. You may ask, Why not just change the original CSS? You can do that and that will work. However, I think it is important to take into account the 5% or so of people who do not have Javascript enabled and since it is really easy to account for those people in this example, I see no reason in not adding the one line necessary to do that.

$(\".submenu\").slideUp(100, function(){$(\".menu_item\").css({overflow:\'visible\'})});
$(\".menu_item\").hover(
function(){
$(\".submenu\", this).slideDown(500);
},function(){
$(\".submenu\", this).slideUp(500);
}
);

This new line is going to slide up all of the submenus while they are still hidden. I have made it last 100 milliseconds so that it does it really quickly (we want to avoid anyone accidentally seeing it closing if they hover over it too early). After that, I have a function that runs when the animation is complete. This is going to make the overflow visible for all of the menu items. The reason for this, instead of just letting the CSS deal with the overflow visibility, is that if you just let CSS do it\'s thing you will not see the submenu slide up. Instead it will just disappear because everything gets hidden instantly rather than waiting for the animation to finish. Since all of the submenus are a height of 0px anyways, we can just make the overflow visible for all of the menu items and leave it at that.

As mentioned by Brektzar in the comments, there is still one more issue with our menu. If you go all out crazy on our menu hovering on and off over and over as fast as you can, then stopping abruptly you will see that the menus keep opening and closing. The reason for this is that jQuery keeps a queue of all the animations it needs to run through. So every time we hovered over a menu_item we added an animation (opening the menu) to the queue, the when we took our mouse off we added yet another one (closing the menu). As you can see, it adds up quickly. Eventually I came up with a fix that works reasonably well, without having to use a variable to get the original height and using animate() instead. It takes just one line:

if($(\".submenu\", this).queue().length < 2)

Just put that on the line right above the \"$(\".submenu\", this).slideDown(500); line and you should be good. What this line does is finds the the current length of the queue. If there are 2 or more animations in line (open and close), it will not add another animation to it. This means it will only add the animation to open the submenu if the submenu is closed or closing.

As a small side note, I would like to say that at first I did try to use clearQueue() and stop() in various locations in the code. This created a new problem: If I hovered on and off too quickly I found that after a bit the menus would stop opening all the way. What happened was that, no matter how I did it with the slideDown, slideUp, or even slideToggle, was it would grab the height of the submenu as it was closing. This meant the original height to open it all the way is gone and instead it would use a height somewhere in between. That\'s as bad, if not worse, than the original problem.

You can also do many other animations with your menus, such as fading in and out as you hover. All you would have to do is go to the jQuery site as mentioned before and find the effect you want. In case you need some help getting all of the jQuery together, you can see it below. I have also loaded up a demo page if you want to check that out.

$(document).ready(function(){
$(\".submenu\").slideUp(100, function(){$(\".menu_item\").css({overflow:\'visible\'})});
$(\".menu_item\").hover(
function(){
if($(\".submenu\", this).queue().length < 2)
$(\".submenu\", this).slideDown(500);
},function(){
$(\".submenu\", this).slideUp(500);
}
);
});

Popular Now

Comments