【问题标题】:Menu with mouseenter & mouseleave events带有 mouseenter 和 mouseleave 事件的菜单
【发布时间】:2012-12-08 19:28:17
【问题描述】:

简介:
大家好。我正在尝试做一个菜单,但我遇到了 mouseenter/mouseleave 事件。

我目前所拥有的:

$("#icon").click(function() {
    $("#invis").css("display", "block");
    $("#icon").bind("mouseleave", function(){
        $("#invis").css('display', "none");
    }).bind("mouseenter", function(){
        $("#invis").css('display', "block"); 
    });
    $("#invis").bind("mouseleave", function(){
        $("#invis").css('display', "none");
    }).bind("mouseenter", function(){
        $("#invis").css('display', "block");
    });
});​  

到目前为止,我试过这个。我的意思是单击“图标”,此单击将显示菜单/另一个隐藏元素。现在我想让它保持打开状态,因为有人将鼠标悬停在“图标”或实际菜单上。但是使用我提供的代码,一旦我离开鼠标然后在“图标”上再次输入,它仍然会保持 onmouseenter 事件,并且菜单将再次出现。我知道我可以取消绑定 onmouseenter 事件,但是一旦我离开菜单,进入图标,我的菜单就会关闭,我不希望这样。

我能想到的最简单的例子:http://jsfiddle.net/tzzqM/5/

问题
如何在单击事件时打开“菜单”,然后只要有人将鼠标悬停在菜单或“图标”(两者)上,就保持打开状态。一旦鼠标离开两者的区域,菜单就会关闭,要打开它,我需要再次单击“图标”。 有没有其他方法可以做到这一点?

【问题讨论】:

    标签: javascript jquery mouseevent


    【解决方案1】:

    当鼠标离开对象时,检查鼠标是否仍然在菜单或菜单按钮上,如果没有,隐藏菜单。基本上,您将事件mouseleave 绑定到两个元素,然后检查选择的长度。如果是1,你要么在菜单上,要么在按钮上,这使得退出菜单按钮进入菜单本身,不会触发代码的“隐藏”部分,如果选择长度为0,那么我们还没有结束任何这些元素,我们都会隐藏它。

    $("#icon").click(function() {
        $("#invis").css("display", "block");
            $("#invis,#icon").bind("mouseleave", function(){
                if($("#invis:hover,#icon:hover").length === 0){
                    $("#invis").css('display', "none");
                }
            })
    });​
    

    有一个小提琴here。

    或者如果我必须从头开始(只是 jQuery 部分)我会写它的方式,因为请记住,您跳入 DOM 池的次数会更少,并且 应该 有点效率更高一些,尽管它与第一个功能一样。这是fiddle

    var icon = $("#icon"),
        menu = $("#invis");
    
    icon.click(function() {
        menu.show();
            $.merge(icon,menu).bind("mouseleave", function(){
                if($("#icon:hover,#invis:hover").length < 1) menu.hide();
            });
    });​
    

    或者使用 jhummel 的建议,我们可以访问具有悬停的新视图的 id,并检查它是否是我们要监控的两个视图之一。这很棒,因为它可以防止我们再次跳入池中,这给我们带来了边际性能提升,这里是 fiddle。

    var icon = $("#icon"),
        menu = $("#invis");
    
    icon.click(function() {
        menu.show();
            $.merge(icon,menu).bind("mouseleave", function(e){
                if($.inArray(e.relatedTarget.id, ["icon","invis"]) === -1){
                       menu.hide();
                }
            });
    });​
    

    ​


    相关文档:

    【讨论】:

    • 我喜欢链接到我的答案中使用的方法(不是所有方法,只是不常见的方法),因此人们实际上会阅读文档。很高兴我能帮上忙。
    • 非常好!喜欢使用 $.merge
    【解决方案2】:

    当您使用mouseover 或mouseleave 事件时,jQuery 中的事件对象将具有relatedTarget 属性。您可以检查该属性以查看鼠标是否正在进入其他元素。

    $("#icon").on('click',function() {
      $("#invis").show();
    }).on('mouseleave', function(e) {
      if(e.relatedTarget.id != 'invis') $('#invis').hide();    
    });
    
    $('#invis').on('mouseleave', function(e) {
      if(e.relatedTarget.id != 'icon') $(this).hide();
    });
    

    jquery relatedTarget docs ​

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多