HTML:
<ul class="topnav">
<li><a href="#"><span>One</span></a></li>
<li><a href="#"><span>Two</span></a></li>
<li>
<li><a href="#"><span>Three</span></a></li>
<ul class="subnav">
<li><a href="#">A</a></li>
<li><a href="#">B</a></li>
<li><a href="#">C</a></li>
</ul>
</li>
</ul>
jquery:
var timeout = null;
$(document).ready(function() {
$("ul.topnav li").mouseover(function() {
if (timeout) clearTimeout(timeout);
$(this).find("ul.subnav").slideDown('fast').show();
}).mouseout(function() {
timeout = setTimeout(closemenu, 500);
});
// sub menu mouseovers keep dropdown open
$("ul.subnav li").mouseover(function() {
if (timeout) clearTimeout(timeout);
}
).mouseout(function() {
timeout = setTimeout(closemenu, 500);
// alert(timeout);
});
// any click closes
$(document).click(closemenu);
});
// Closes all open menus
function closemenu() {
$('ul.subnav:visible').hide();
if (timeout) clearTimeout(timeout);
}
I'm having issues with timeout. In use, if i mouseover "Three", the dropdown stays out forever. if i mouseover "A", dropdown will stay out forever, but if I mouseover "B" or anything lower, the menu will close on me. if you uncomment "// alert(timeout);" it gets there for B, (and A) but timeout will have a value. why is this? i thought clearTimeout would null the timeout variable?
youre trying to build a drop down menu? why not use existing jquery plugins for that or better yet, css-only drop down menu like http://purecssmenu.com/?
You can simplify your code overall by using
.hover()
and.data()
like this:You can see a working demo here
Instead of sharing a global
timeout
variable, this sets a timeout per top level<li>
, each one has an independent timer, and when you hover back over that element, only its timer is cleared. Also.hover()
usesmouseenter
andmouseleave
, rather thanmouseover
andmouseout
, the difference is when you go into a child or between children,mouseenter
doesn't fire again, andmouseleave
doesn't fire on the parent<li>
we care about.You can test this with the demo link above, I added sub-items to the first menu as well, to demonstrate they're independent. If you happen to have question about the
$.proxy
in there, it's just makingthis
inside that timeout anonymous function refer to what I want it to (the currentthis
)...the element that needs closing after the timeout.