Reputation: 11
i have this html code:
<ul id="nav">
<li>Heading 1
<ul>
<li>Sub page A</li>
<li>Sub page B</li>
<li>Sub page C</li>
</ul>
</li>
<li>Heading 2
<ul>
<li>Sub page D</li>
<li>Sub page E</li>
<li>Sub page F</li>
</ul>
</li>
</ul>
With this JS code:
$(function(){
$('#nav>li>ul').hide();
$('#nav>li').mouseover(function(){
if ($('#nav ul:animated').size() == 0) {
$heading = $(this);
$expandedSiblings = $heading.siblings().find('ul:visible');
if ($expandedSiblings.size() > 0) {
$expandedSiblings.slideUp(500, function(){
$heading.find('ul').slideDown(500);
});
}
else {
$heading.find('ul').slideDown(1000);
}
}
});
})
For now the code works this way: When click on Heading 1, menu is expanded. When click on Heading 2, heading2 submenu menu is expanded and heading 1 submenu is closed. I need to rework it to this: Submenus must be closed automatically on mouseout. Can somebody help me? Thanks in advance!
Upvotes: 1
Views: 1745
Reputation: 1
I'm doing it with the .hover(function ()
and .mouseLeave (function ()
and it works wonderfully:
$('ul.expanded>li>ul').hide();
$('ul.expanded>li').hover(function(){
if ($('ul.expanded ul:animated').size() == 0) {
$heading = $(this);
$expandedSiblings = $heading.siblings().find('ul:visible');
if ($expandedSiblings.size() > 0) {
$expandedSiblings.slideUp(1000, function(){
$heading.find('ul').slideDown(500);
});
}
else {
$heading.find('ul').slideDown(500);
}
}
}).mouseleave(function() {
var $heading = $(this);
window.setTimeout(function() {
if ($('ul.expanded ul:animated').size() == 0) {
$heading.find('ul').slideUp(1000);
}
}, 0);
});
Upvotes: 0
Reputation: 4860
Try this but you will probably have to add some delays to make a smooth user experience.
$(function(){
$('#nav>li>ul').hide();
$('#nav>li').hover(function(){
$(this).children().slideDown(500);
}, function(){
$(this).children().slideUp(500);
});
})
Upvotes: 0
Reputation: 8327
Well, if you want to keep your original setup and add the mouseout functionality, but you find that the mouseout
fires before the mouseover
, you can use the ol' setTimeout
trick:
$(function(){
$('#nav>li>ul').hide();
$('#nav>li').mouseover(function(){
if ($('#nav ul:animated').size() == 0) {
$heading = $(this);
$expandedSiblings = $heading.siblings().find('ul:visible');
if ($expandedSiblings.size() > 0) {
$expandedSiblings.slideUp(500, function(){
$heading.find('ul').slideDown(500);
});
}
else {
$heading.find('ul').slideDown(1000);
}
}
}).mouseout(function() {
var $heading = $(this);
window.setTimeout(function() {
if ($('#nav ul:animated').size() == 0) {
$heading.find('ul').slideUp(500);
}
}, 0);
});
})
Upvotes: 1
Reputation: 630389
This is a slightly different animation (simulateous sliding, rather than one after the other), but if it's an option .hover()
which uses mouseenter
and mouseleave
rather than mouseover
and mouseout
(which fire on children) would be much simpler, like this:
$(function(){
$('#nav>li>ul').hide();
$('#nav>li').hover(function(){
$(this).find('ul').slideToggle(500)
.siblings().find('ul:visible').slideUp(500);
});
})
Upvotes: 1