jQuery悬停依赖于两个元素

jQuery悬停依赖于两个元素,jquery,jquery-hover,Jquery,Jquery Hover,我有主导航和子导航,出于设计原因,它们在单独的分区中。我想在主导航项目悬停时显示相应的子导航,我可以这样做,但如果用户将鼠标移到主导航项目外并移到子导航区域,我还想保持子导航打开。最后一部分是我被卡住的地方 我正在考虑悬停,我需要用setTimeout()和IF语句做些什么,但我还没有在这方面取得任何进展。这是一种值得尝试的方法吗 HTML: 尝试对mouseenter和mouseleave使用单独的事件处理程序,而不是使用.hover()方法。mouseenter将仅连接到mnav按钮,而mo

我有主导航和子导航,出于设计原因,它们在单独的分区中。我想在主导航项目悬停时显示相应的子导航,我可以这样做,但如果用户将鼠标移到主导航项目外并移到子导航区域,我还想保持子导航打开。最后一部分是我被卡住的地方

我正在考虑悬停,我需要用setTimeout()和IF语句做些什么,但我还没有在这方面取得任何进展。这是一种值得尝试的方法吗

HTML:


尝试对mouseenter和mouseleave使用单独的事件处理程序,而不是使用.hover()方法。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>

无功定时器;
$(文档).ready(函数(){
$(“#mnav”).mouseenter(函数(){
$(“#snav”).slideDown();
});
$(“#mnav,#snav”).mouseleave(函数(){
timer=setTimeout(“$('#snav').slideUp();”,50);
});
$(“#mnav,#snav”).mouseenter(函数(){
清除超时(计时器);
});
});

以下内容适用于您,我做了一些更改:

  • 用于在进入子AV时停止动画
  • 将幻灯片移到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');
});

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

但是,在打开菜单之前,您还需要一段延迟时间——这既可以避免令人讨厌的“飞越”激活,也可以减少在离开主菜单时意外从sub1切换到sub2的常见情况

因此,问题代码需要:

  • 悬停在子菜单
    ul
    元素上
  • stop
    在鼠标选择更改时停止运行动画
  • 一个可重置的定时器,控制打开和关闭
  • 总而言之:

    $("#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
    上需要额外的操作,以便在子菜单之间中断交换后进行清理。

    您能给我一个mouseleave事件处理程序的示例吗,即使它是伪代码?我尝试了一下,但告诉我“TypeError:$不是函数”!!!$在设置超时时未检测到@Nguyen AAAAA,你就是那个人。它工作得很好。谢谢你,谢谢你,非常感谢你。这非常有效!非常感谢您抽出时间来整理这些内容,您真的帮了我大忙,也教了我很多。我不想把它讲得太长,但您是否想过重构,以允许默认情况下在页面上打开子AV?这可能会很棘手,最好打开一个新问题。说明即使用户打开一个关闭的子菜单,您是否希望某些子菜单保持打开状态。基本思想是hover out函数恢复任何默认状态。最好使用CSS类,而不是
    隐藏
    显示
    。我发布了另一个问题。在我遇到如何知道/保存菜单的初始状态的问题之前,您描述的逻辑似乎很简单。
    $("#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');
    });
    
    $("#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);
    }