JQuery is dependent on two elements

I have basic navigation and sub-navigation, which for design reasons are in separate DIVs. I would like to show the corresponding sub-navigation when the main navigation element is hovering, what can I do, but I also want the sub-nav to open if the user moves his mouse outside the main navigation element and in the sub-nav. The last part is where I get stuck.

I think that I need to do something with setTimeout () and the IF statement, but I could not make any progress in this area. Is this even an approach worth a try?

HTML:

<div id="mnav"> <ul id="buttons"> <li class="one"><a href="#">Main 1</a></li> <li class="two"><a href="#">Main 2</a></li> <li class="three"><a href="#">Main 3</a></li> <li class="four nav-dark"><a href="#">Main 4</a></li> </ul> </div> <!-- /mnav --> <div id="snav"> <ul class="snav-one"> <li><a href="#">Sub 1.1</a></li> <li><a href="#">Sub 1.2</a></li> <li><a href="#">Sub 1.3</a></li> <li><a href="#">Sub 1.4</a></li> <li><a href="#">Sub 1.5</a></li> <li><a href="#">Sub 1.6</a></li> </ul> <ul class="snav-two"> <li><a href="#">Sub 2.1</a></li> <li><a href="#">Sub 2.2</a></li> </ul> </div> <!-- /snav --> 

JS:

 $(document).ready(function() { $("#buttons li.one, #buttons li.two").hover(function(){ var subnav = 'ul.snav-' + $(this).attr('class'); $("#snav").slideDown('fast').addClass("open").find(subnav).show(); }, function(e){ var subnav = 'ul.snav-' + $(this).attr('class'); $("#snav").slideUp('fast').removeClass("open").find(subnav).hide(); }); }); 
+6
source share
3 answers

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.

+8
source

Instead of using the .hover () method, try using separate event handlers for mouseenter and mouseleave. The mouse center will be attached only to the mnav buttons, and the mouse will be attached to both the mnav button and the snav div. On your mouseleave functions, you probably have to add a little timeout and check if they moved from one element to another.

Try something like this:

 <script> var timer; $(document).ready(function() { $("#mnav").mouseenter(function() { $("#snav").slideDown(); }); $("#mnav, #snav").mouseleave(function() { timer=setTimeout("$('#snav').slideUp();",50); }); $("#mnav, #snav").mouseenter(function() { clearTimeout(timer); }); }); </script> 
+4
source

See example β†’

The following should work for you: I made a few changes:

  • used the .stop() method to stop the animation when entering subnav
  • moved the slides to subnav ul instead of the container so that the above works
  • some other things

See below:

 $("#buttons li.one, #buttons li.two").hover(function() { var subnav = 'ul.snav-' + $(this).attr('class'); $("#snav").find('ul').slideUp('fast'); $("#snav").addClass("open").find(subnav).stop(true, true).slideDown('fast'); }, function(e) { var subnav = 'ul.snav-' + $(this).attr('class'); $("#snav").removeClass("open").find(subnav).slideUp('fast'); }); $('#snav').bind('mouseenter', function(e) { $(this).find('ul').stop(true, false); }).bind('mouseleave', function(e) { $(this).find('ul').stop(true, true).slideUp('fast'); }); 

See example β†’

+1
source

Source: https://habr.com/ru/post/889051/


All Articles