7

由于设计原因,我有主导航和子导航,它们位于单独的 DIV 中。我想在主导航项悬停时显示适当的子导航,我可以这样做,但是如果用户将鼠标移到主导航项之外并进入子导航,我也想保持子导航打开-导航区域。最后一部分是我卡住的地方。

我正在考虑悬停时我需要使用 setTimeout() 和 IF 语句做一些事情,但我无法在该领域取得任何进展。这甚至是一种值得尝试的方法吗?

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();
 });
});
4

3 回答 3

8

对于鼠标菜单人体工程学,您希望在从主菜单到子菜单时有一点延迟,因此子菜单在鼠标到达之前不会关闭。(正如问题所说。)

但是,您还需要在菜单打开之前进行延迟——既可以避免烦人的“飞越”激活,又可以减少在离开主菜单时意外从sub1切换到sub2的常见情况。

所以,问题代码需要:

  1. hover在子菜单ul元素上。
  2. stop如果鼠标选择发生变化,则停止运行动画。
  3. 一个可复位的定时器,控制打开和关闭。

请参阅 jsFiddle 上的演示

把它们放在一起:

$("#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);
}



请注意 , 上所需的额外操作#snav ul,以在子菜单之间的中断交换后进行清理。

于 2011-05-26T02:19:22.573 回答
4

不要使用 .hover() 方法,而是尝试对 mouseenter 和 mouseleave 使用单独的事件处理程序。mouseenter 将只附加到 mnav 按钮,而 mouseleave 将附加到 mnav 按钮和 snav div。在您的 mouseleave 函数中,您可能必须添加一个小超时并检查它们是否从一个元素转到另一个元素。

尝试这样的事情:

<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>
于 2011-05-26T00:34:40.220 回答
1

查看示例 →

以下应该对你有用,我做了一些改变:

  • 使用该.stop()方法在进入 subnav 时停止动画
  • 将幻灯片移动到 subnav ul 而不是容器,这样上面的方法就可以了
  • 其他一些事情

见下文:

$("#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');
});

查看示例 →

于 2011-05-26T00:44:33.440 回答