Milen
Milen

Reputation: 11

jQuery expanding menu

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

Answers (4)

Werner
Werner

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

Paul
Paul

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

Spiny Norman
Spiny Norman

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

Nick Craver
Nick Craver

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

Related Questions