For ergonomics of the mouse menu, you need a slight delay when the mouse is from the main to the submenu, so the submenu does not close before the mouse gets there. (As stated in this question.)
But you also need a delay before opening the menu - both to prevent the annoying activation of the "flyover" and to reduce the overall appearance of an accidental switch from sub1 to sub2 when moving away from the main menu.
So, the question code needs the following:
hover in the ul .stop to stop the animation when the mouse changes.- A resettable timer that controls both open and closed.
See the demo in jsFiddle .
Putting it all together:
$("#buttons li.one, #buttons li.two").hover ( function () { MenuOpenCloseErgoTimer ( 100, function (node) { var subnav = 'ul.snav-' + $(node).attr ('class'); $("#snav ul").hide (); $("#snav").stop (true, true).slideDown ('fast').addClass ("open").find (subnav).show (); }, this ); }, function () { MenuOpenCloseErgoTimer ( 200, function () { $("#snav").stop (true, true).slideUp ('fast').removeClass ("open").find ('ul').hide (); } ); } ); $("div#snav ul").hover ( function () { MenuOpenCloseErgoTimer ( 0, function () { $("#snav").stop (true, true).slideDown ('fast').addClass ("open"); $(this).show (); } ); }, function () { MenuOpenCloseErgoTimer ( 200, function () { $("#snav").stop (true, true).slideUp ('fast').removeClass ("open"); $("#snav ul").hide (); } ); } ); function MenuOpenCloseErgoTimer (dDelay, fActionFunction, node) { if (typeof this.delayTimer == "number") { clearTimeout (this.delayTimer); this.delayTimer = ''; } if (node) this.delayTimer = setTimeout (function() { fActionFunction (node); }, dDelay); else this.delayTimer = setTimeout (function() { fActionFunction (); }, dDelay); }
Note the additional operations necessary for #snav ul to clear after interrupted swaps between submenus.
source share