Simple vertical accordion menu using JQuery
I saw various tutorial and jquery snippets to create accordion menu, but most of them were only on mousehover event but nothing with mouse out event.A hectic problem can persist when we try to render the accordion effect with mouseover and mouseout event. So we need to use jquery mouse event i.e ‘hover’ or ‘mouseenter’ and ‘mouseleave’.
What is the problem with ‘mouseover’ and ‘mouseout’ event?
Hovering over children element fires parent’s mouseout event which most of the time dont require.This is caused by event bubbling / propagation.
So we have to use ‘mouseenter’ and ‘mouseleave’ , or ‘hover’ event instead.
Note: Javascript does not provide the direct ‘hover’ event but we can get it using javascript framework eg. ‘Jquery’ .
HTML Stucture
<div id="accordion"> <ul> <li class="selected"> <a href="http://prabeengiri.com.np"> Category1 </a> <ul> <li> <a href="http://prabeengiri.com.np">subcategory1 </a></li> <li> <a href="http://prabeengiri.com.np"> subcategory2 </a></li> </ul> </li> <li> <a href="http://prabeengiri.com.np"> Category2 </a> <ul> <li> <a href="http://prabeengiri.com.np"> subcategory5 </a></li> <li> <a href="http://prabeengiri.com.np"> subcategory1 </a></li> </ul> </li> <li> <a href="http://prabeengiri.com.np"> Category3 </a> <ul> <li> <a href="http://prabeengiri.com.np"> subcategory5 </a></li> <li> <a href="http://prabeengiri.com.np"> subcategory1 </a></li> </ul> </li> </ul> </div>
In the above html , ‘selected’ class has been provided to ‘li’ to make that particular ‘li’ active.And also do not forget to provide the class ‘parentCategory’ to parent ‘li’.
Css for accordion Menu
<style> #accordion {width: 350px;margin: 0 auto;font-family: Verdana, Arial, Helvetica, sans-serif;font-size: 12px;float:left;} #accordion ul {list-style:none outside none;margin: 0px;padding: 0px;} #accordion ul li {display: block;background: #ccc;border-bottom: 1px solid #e1e1e1;} #accordion ul li a {font-weight: bold;color: #787878;padding: 4px 10px;} #accordion ul li li a {font-weight: bold;color: #FFFFFF;padding: 3px 10px;} #accordion ul li ul {padding: 0 0 0 0px;display:none;} #accordion ul li li {display: block;background: #A6A6A6;border-bottom: 1px solid #ddd;} #accordion a { display:block;text-decoration: none;} </style>
Now its turn of main hero;
JQuery to render vertical accordion menu
<script type="text/javascript"> jQuery(document).ready(function(){ jQuery("#accordion ul li:not('.selected')").hover(function(){ jQuery(this).find("ul").stop(true,true).slideDown(400).parent().siblings("li:not('.selected')").find('ul').slideUp(400); },function(){ jQuery("#accordion ul li:not('.selected')").find("ul").slideUp(400); }).siblings('.selected').find('ul').show(); }) </script>
These kind of effects seems difficult to render……………… unless…. you get familiar with JQuery
If you any kind of queries then please feel free to contact me. I will be pleased to help if something is related to my post.


The vertical accordion menu is really great job, they way your explanation about your script is understandable.
Wish to see your next post soon………
excellent, I am using but….is their an ‘easy’ way to change the javascript so that user can ‘Close’ all the elements?
Yes there is many ways to close all the elements , but prime thing is how you want it to be closed.
Removing the class ‘selected’ from the first ‘li’ will also close all the elements by default. Use of class ‘selected’ is to notify that this particular parent category is active currently.
Can you write in brief how you want it be closed. If clicked on the parent category if its already open or by someother ways. May be when some other event is fired .
Please let me know . I will be glad to help .
If you want this to happen on click event , you can try with this snippet.
jQuery(document).ready(function()
{
jQuery(“#accordion ul li.parentCategory”).click(function(e)
{
e.preventDefault();
jQuery(this).find(“ul”).stop(true,true).slideToggle(400).parent().siblings().find(‘ul’).slideUp(400);
});
});
need help urgently.
is there a way to add another sub-subcategory?
i’m unable to figure it out. adding another and doesn’t work.
@suman well with the jquery snipped and its usage , i dont think it is possible to render the same accordion effect with the same style. Here i will provide u an example , lets say you have sub-sub category under subcategory1 i.e subcategory1.1 and subcategory1.2. . When you hover above the subcategory1 then its child (subcategory1.1 and subcategory1.2) gets displayed . and in this stage when you hover on the subcategory2 then the child of subcategory1 gets slide up which triggers the ‘hover’ event of other ‘li’ lets say category3 but not of subcategory2. So u have to use otherstyle of accordion menu , may be subcategory displays right or left of the parent category . I hope you will understand . Thanks
too bad.
i’ve got what i needed already although this code is very simple.
keep up the good work.
can we implement that menu with hoverintent? if yes kindly tell steps that how we can implement it.
Excellent work
I have not tried with ‘hoverintent’ yet, you can try it by yourself. If you still cannot make it, then I will look at it for you………..;)
how i can implement the delay(),fadeIn(),fadeOut() functions?
can you please guide me so that when i hover the mouse it delay opening and show it in fade.
Thanks
@emaad
I didnt get what exactly what u want, But I have tried to managed to write code using delay(), fadeIn(), fadeOut().
I dont know this will work for you or not. It not can u write in precise what exactly u want . Here is the code.
jQuery(document).ready(function(){
jQuery(“#accordion ul li:not(‘.selected’)”).hover(function(){
//jQuery(this).find(“ul”).stop(true,true).slideDown(400).parent().siblings(“li:not(‘.selected’)”).find(‘ul’).slideUp(400);
jQuery(this).find(“ul”)
.stop(true,true)
.delay(500)
.fadeIn(900)
.parent()
.siblings(“li:not(‘.selected’)”)
.find(‘ul’)
.delay(500)
.fadeOut(900);
},function(){
jQuery(“#accordion ul li:not(‘.selected’)”).find(“ul”)
.delay(500)
.fadeOut(900);
}).siblings(‘.selected’).find(‘ul’).show();
});
this code not working,
ok let me explain you what i want to do,
at the moment your menu working perfectly on my website but its quite too fast for closing the menu
kindly check this link and third example
http://cherne.net/brian/resources/jquery.hoverIntent.html
i want that the menu take some second to show and again take some time to close but the best it for closing if you check that link and third example you come to know that how its working…..kindly help me out to solve this problem.
@emaad
Here is the snippet that will meet your requirement.It will act as hoveintent.
jQuery(document).ready(function(){
var _delay = 500;//delay before slide…….
jQuery(“#accordion ul li:not(‘.selected’)”).hover(function(){
jQuery(this)
.find(“ul”)
.stop(true,true)
.delay(_delay )
.slideDown(400)
.parent()
.siblings(“li:not(‘.selected’)”)
.find(‘ul’)
.slideUp(400);
},function(){
jQuery(“#accordion ul li:not(‘.selected’)”).find(“ul”)
.delay(_delay )
.slideUp(‘slow’);
}).siblings(‘.selected’).find(‘ul’).show();
});
Change the value of ‘var _delay’ to increase or decrease the slider delay…….
I hope this helps
Hi Prabeen,
Your menu works very well on my site, however, I am experiencing some problems trying to click on the subcategory of each menu and go there. In other words, the subcategory does not work when I tried this click event snippet as follows:
jQuery(document).ready(function()
{
jQuery(”#accordion ul li.parentCategory”).click(function(e)
{
e.preventDefault();
jQuery(this).find(”ul”).stop(true,true).slideToggle(400).parent().siblings().find(’ul’).slideUp(400);
});
});
May I know what does the preventDefault() function do as according to your code? Thanks!!
@dandelia……
Thanks for the comment .
e.preventDefault()
prevents the default behaviour of the current event.
Snippet you have used wont work with the sub categories because the event attached to the dom element is only for the element with class =’parent category” . So its not working I guess. Can u please send how exactly u wanted it to happen in more details .
Hi Prabeen,
I would want the accordion menu to open a subcategory ONCE upon click, therefore displaying the subcategory (which can be clickable).
The subcategory stays opened and the list items within the subcategory can be clicked upon to show each sub page within the site.
In other words, i just want the list items within the subcategory to be clickable that’s all….
@dandelia
you can use this snippet instead , but make sure u have class as ‘parentCategory’ on the first ‘li’
jQuery(document).ready(function(){
jQuery(“#accordion ul li a”).click(function(e){
if (!$(this).parent().hasClass(‘parentCategory’)) e.preventDefault();
jQuery(this).siblings(“ul”).stop(true,true).slideToggle(400).parent().siblings().find(‘ul’).slideUp(400);
});
});
I hope this helps
Hi Prabeen,
Thanks for your help. But this time round the subcategory cannot be displayed!! What should I do? Is there something wrong somewhere in the new code that you have given me? =(
Hi Prabeen,
How can I work on the following snippet with the e.preventDefault function removed? So that the links can be made clickable in this manner. So far everything is working fine on my site except that all the links are not clickable.
jQuery(document).ready(function()
{
jQuery(“#accordion ul li.parentCategory”).click(function(e)
{
e.preventDefault();
jQuery(this).find(“ul”).stop(true,true).slideDown(400).parent().siblings().find(‘ul’).slideUp(400);
});
});
Click event is attached to ‘li’ element. so I dont guess e.preventDefault has anything to do in your snippet. If it has been atttached to ‘a’ element , then it just prevents the default behaviour of anchor tag.
Does it meet your requirement when you omit e.preventDefault().
Can u try with this snippet
jQuery(document).ready(function(){
jQuery(”#accordion ul li a”).click(function(e){
if (!$(this).parent().hasClass(’parentCategory’)) e.preventDefault();
jQuery(this).siblings(”ul”).stop(true,true).slideToggle(400).parent().siblings().find(’ul’).slideUp(400);
});
});
If that did not help you , can u please tell me if there is any javascript error on error console and your html structure………
Hi Prabeen,
There is no javascript error on the error console, but the links in the accordion menu cannot expand now!! They are now clickable but cannot expand this time…
I don’t think the new snippet works for me, I want the links to be clickable and can expand at the same time.
Here is my html structure: