简体   繁体   中英

jquery - sub menu is hidden on mouseout of main menu

This seems like a pretty easy one, but I couldn't solve my issue by reading the related questions here on SO.. so here's mine. I have:

<ul class="main-menu">
    <li>Letters</li>
    <li>Numbers</li>
</ul>

<ul class="sub-menu hidden">
    <li>A</li>
    <li>B</li>
    <li>C</li>
</ul>

I want .sub-menu to appear on mouseover of .main-menu, and keep visible while the mouse is over both .main and sub.

$(".main-menu, .sub-menu").hover(
    function(){
        $('.sub-menu').hide().removeClass('hidden').slideDown('fast');
    }, function(){
        $('.sub-menu').slideUp('fast');
    }
);

But mouseout is fired when I mouseout of main-menu, even though I mouseout of it into sub-menu, so the sub-menu is hidden.

Any suggestions? Restructuring the HTML is not an option, though.

The following assumes you have a second sub-menu to go with the "Numbers" main-menu item, something like I've shown here: http://jsfiddle.net/aY7wW/ - and further assumes that when you said "Restructuring the HTML is not an option" you meant that I couldn't even suggest adding attributes to associate each sub-menu with its main-menu item. To work within this restriction I've used the main-menu li element index to relate to the sub-menu ul element index (obviously this works only if the sub-menus are defined in the same order as the corresponding main-menu items). If you could add some id attributes or something it would simplify the code somewhat, but anyway:

var timerId,
    $mainMenuItems = $(".main-menu li"),
    $subMenus = $(".sub-menu");

$mainMenuItems.hover(
    function(){
        clearTimeout(timerId);
        $subMenus.slideUp('fast');
        $($subMenus[$mainMenuItems.index(this)]).hide()
                                                .removeClass('hidden')
                                                .slideDown('fast');
    }, function(){
        var i = $mainMenuItems.index(this);
        timerId = setTimeout(function(){$($subMenus[i]).slideUp('fast');},500);
    }
);
$subMenus.hover(
    function() {
       clearTimeout(timerId);
    },
    function() {
       $(this).slideUp('fast');
    }
);

The basic idea is to use setTimeout() to delay hiding the sub-menu on mouseout from the main-menu. This gives you time to move the mouse over the sub-menu, and if you do the timeout is cleared so it won't be hidden. Then when you move the mouse off the sub-menu it is hidden. But allowing for movement of the mouse just between the different main-menu items, on initial hover we also clear any outstanding timeout and hide previously shown sub-menus so that only the correct sub-menu will show. I've used a delay of 500ms, but obviously you can set that to whatever feels natural for you.

Working demo: http://jsfiddle.net/aY7wW/

尝试将主菜单和子菜单都放在div中,然后将悬停事件放在div中。

How about something like:

$(".main-menu").mouseover(function () {
    $('.sub-menu').slideDown('fast').click(function (){
        $(this).slideUp('fast');
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM