1

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

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

  1. 当鼠标离开菜单按钮或子菜单本身时,如何隐藏菜单
  2. 有没有一种更优雅的方法来做到这一点,而不是为每个按钮编写 jQuery(换句话说,我可以编写更通用的代码,适用于每个按钮)。

这是我目前使用的 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();
        });
    });
});
4

6 回答 6

5

好的,我们开始吧。首先,为了让“子菜单”更容易隐藏,我给每个子菜单添加了一个类。这为调用提供了一个焦点,不仅在 CSS 中,而且在 jquery 分配中也是如此。

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

在css中,除了给子菜单一个隐藏显示和一个相对位置外,我这里并没有什么特别之处。现在你可以重新设计你喜欢的方式,我在这里给出了相对位置,以便子菜单可以使用top.

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

有了这些,我们就可以使用 JavaScript 了……几乎!还有一件事!在你的菜单 HTML 中,我为每个图像添加了一个数据变量。我用这个变量来保存ID每个.sub-menu. 现在这不是必需的,毕竟,您可以做一个复杂的语句来使用从图像 id 中删除单词按钮并将其更改为菜单,但是为什么要复杂呢?

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

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

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

完整的工作示例


根据评论修复

$(function() {
    var tmrSubMenu;
    $(document).on("mouseenter", "#topMenu > img", function(e) {
        $(".sub-menu").hide();
        var menu = $(this).data("submenu");
        $(menu).css("top", $(this).position().top-9).show();
    })
    .on("mouseleave", "#topMenu > img", function(e) {
        var menu = $(this).data("submenu");
        tmrSubMenu = setTimeout(function() { $(menu).hide(); }, 100);
    })
    .on("mouseenter", ".sub-menu", function(e) {
        clearTimeout(tmrSubMenu);
    })
    .on("mouseleave", ".sub-menu", function(e) {
        $(this).hide();
    })
})
于 2013-06-19T14:16:43.603 回答
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();
        });
    });
})
于 2013-06-19T13:46:19.450 回答
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();
        }
    );
})
于 2013-06-19T13:55:22.587 回答
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/

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

于 2013-06-19T14:34:20.387 回答
0
$(document).ready(function(){
    $('#request-it-menu').hide();

    $('#request-it-button, #request-it-menu').hover(function() {
        $('#request-it-menu').toggle();
    });
});
于 2013-06-19T13:55:31.783 回答
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 事件能够检测鼠标离开,但它们也存在鼠标从一个菜单项到下一项的问题。这也将触发隐藏菜单调用。当鼠标悬停时,我将变量“显示”设置为 true,鼠标悬停时设置为 false。当您跨项目移动时,它们会翻转两次。然后在 20ms 延迟后,检查最终显示的变量值以确保隐藏事件有效。

当您使用此代码时,请像这样调用它:

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

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

于 2013-06-23T19:50:16.747 回答