关于Mouseleave事件的jQuery隐藏菜单

时间:2013-06-19 13:40:41

标签: jquery

我有以下网站设置[网站位置已编辑] (它刚刚开始,所以只有顶部按钮和第一级菜单有效):

当您将鼠标悬停在“请求”按钮上时,会弹出“请求菜单” 我需要弄清楚两件事:

  1. 当鼠标离开菜单按钮或子菜单本身和
  2. 时,如何让菜单隐藏起来
  3. 有没有更优雅的方式来做这个而不是为每个按钮编写jQuery(换句话说,我可以编写更多适用于每个按钮的通用代码)。
  4. 这是我到目前为止使用的jQuery:

    $(document).ready(function(){
        $('request-it-menu').hide();
        $('#request-it-button, #request-it-menu').mouseenter(function() {
            $('#request-it-menu').show();
            $('#request-it-button, #request-it-menu').mouseleave(function() {
                $('request-it-menu').hide();
            });
        });
    });
    

6 个答案:

答案 0 :(得分:5)

好的,我们走了。首先,为了使“子菜单”更容易隐藏,我在每个子菜单中添加了一个类。这使得一个焦点不仅可以在CSS中调用,还可以调用jquery分配。

<div id="request-it-menu" class="sub-menu">

在CSS中,除了给子菜单隐藏显示和相对位置外,我没有太多特别之处。现在您可以重新设计自己喜欢的方式,我在这里给出了相对位置,以便可以使用top定位子菜单。

.sub-menu { display: none; position: relative; }

有了这一切,我们几乎可以使用JavaScript ......还有一件事!在你的菜单HTML中,我为每个图像添加了一个数据变量。我使用此变量来保存每个ID的{​​{1}}。现在这不是必要的,毕竟,你可以制作一个复杂的声明来使用从图像id中删除单词按钮并将其更改为菜单,但为什么会变得复杂?

.sub-menu

终于! JavaScript。由于我们的数据变量,在这一点上真的很容易使调用“动态”和“单一”。首先,我使用jQuery的.on()方法的委托版本,以使鼠标事件添加到给定选择器的动态元素。选择器本身是一个“Blanket”语句,这意味着它可以抓取所有符合它的简单描述。在这种情况下,我只是将头部菜单ID直接用于img的内部。

<img id="request-it-button" data-submenu="#request-it-menu"

Full Working Example


基于评论修复

$(function() {  //  same as $(document).ready(function() { ...
    //  calling this way in jquery is using "delegate" form of .on
    //  this assures function to even dynamic elements of the fitting selector
    $(document).on("mouseenter", "#topMenu > img", function(e) {
        var menu = $(this).data("submenu");
        //  position part here is temporary till you decide how you want css to arange sub menu's
        $(menu).css("top", $(this).position().top-9).show();
    })
    .on("mouseleave", "#topMenu > img", function(e) {
        var menu = $(this).data("submenu");
        $(menu).hide();
    })
})

答案 1 :(得分:1)

第6行的jquery选择器中有一个拼写错误 - 它应该是$("#request-it-menu").hide()(注意#)。除此之外,您的代码非常完美。

以下是修正后的代码段:

$(document).ready(function(){
    $('request-it-menu').hide();
    $('#request-it-button, #request-it-menu').mouseenter(function() {
        $('#request-it-menu').show();
        $('#request-it-button, #request-it-menu').mouseleave(function() {
            $('#request-it-menu').hide();
        });
    });
})

答案 2 :(得分:1)

通过这种方式,您通常会为所有下一个菜单

完成

html:

<img id="request-it-button" src="request-it.png" alt="request-it" width="220" height="50" data="request-it" class="menu-button">
<img id="repair-it-button" src="repair-it.png" alt="repair-it" width="220" height="50" data="repair-it" class="menu-button">
...

<div id="request-it-menu" style="display: block;" class="request-it menu-context">
...
</div>
<div id="repair-it-menu" style="display: block;" class="repair-it menu-context">
...
</div>
...

JS

$(document).ready(function(){
    //hide all sub menu with the class menu-context
    $('.menu-context').hide();

    //for each element having the class menu-button
    $('.menu-button').hover(
        function() {    //mouseenter
            //find the matching menu designated by the data attribute
            var desig = $(this).prop("data");
            $('.'+desig).show();
        },
        function() {    //mouseleave
            //find the matching menu designated by the data attribute
            var desig = $(this).prop("data");
            $('.'+desig).hide();
        }
    );
})

答案 3 :(得分:0)

$(document).ready(function(){
    $('#request-it-menu').hide();

    $('#request-it-button, #request-it-menu').hover(function() {
        $('#request-it-menu').toggle();
    });
});

答案 4 :(得分:0)

$('.has-hover').hover(
        function () { $('#request-it-menu').addClass("show"); },
        function () { $('#request-it-menu').removeClass("show"); }
    );

和CSS。重新制作样式并删除!important:)

.show {
    display: block !important;
}

这是小提琴:http://jsfiddle.net/tAx6N/

尝试删除菜单和子菜单之间的空格,以防止悬停效果中断。

答案 5 :(得分:0)

过去几周我对这个话题进行了大量的研究。在阅读了很多帖子后,我找不到这个问题的满意答案。所以我决定弄脏手。

这是我写的用于在鼠标移出时隐藏菜单的实用程序脚本:

util.watchMouseOut=function(id,cb){
    this.shown=true;
    this.statecheck={};
    $(id).children().mouseout(function() {
            shown=false;
            dostatecheck();
        }).mouseover(function() {
            shown=true;
            dostatecheck();
        });

    this.dostatecheck=function(){
        try{
            setTimeout(function(){
                try{
                    clearTimeout(this.statecheck);
                }catch(e){}
            },5);
        }catch(e){}
        this.statecheck=setTimeout(function(){
            if(!shown)
            {
                cb();
            }
        },20);
    };

}

这个想法是mouseover和mouseout事件能够检测鼠标离开,但是它们也存在鼠标从一个菜单项到下一个项目的问题。这也会触发隐藏菜单调用。鼠标悬停时我将变量'shown'设置为true,mouseout时设置为false。当您移动物品时,它们会翻转两次。然后在20ms延迟后,检查最终显示的变量值,以确保隐藏事件有效。

使用此代码时,请按以下方式调用:

var watch=new util.watchMouseOut('#menuid',function(){
    hidemenu();
});

您需要在其他地方实现hidemenu()函数。