0

我正在尝试将加载了内联 Javascript 的现有菜单系统转换为仅使用 jQuery 的新的、更高效的代码。

我有一个带有翻转图像的单杠。我在页面中有一个包含整数值的隐藏字段。当页面加载时,相应的菜单会加载一个“粘性”版本的图像,并且所有其他菜单项在鼠标进入和离开时交换图像。它加载了大量的内联 Javascript 和一个怪物 Javascript 文件,每次我创建一个新站点时都很难转换。

我成功地将这一切转换为 jQuery,在那里我还能够禁用对粘性菜单项的单击。现在我可以简单地设置一些变量并根据每个站点的设计轻松自定义它。

工作很棒...

现在又来了一个新问题。一种设计在每个菜单图像下包含一堆滑动抽屉。滑动动画由外部 JS 文件处理,菜单抽屉本身每个都只是一个 DIV,其中包含嵌套在容器 DIV 中的内容。

因此,我为 jQuery 编写了一些简单的东西,它们可以为 DIV 设置动画,并在鼠标悬停时将其滑入和滑出以获取菜单图像。

问题是我似乎无法解决鼠标离开菜单图像并向下移动到菜单抽屉而不关闭抽屉的问题。我明白“为什么?”......我要离开触发动画的图像,在我进入抽屉之前关闭抽屉。如果我将悬停动画应用于抽屉容器,它只会在菜单下创建一个区域,该区域也会触发动画,我也不想要这样。jQuery 似乎变成了一个更复杂的问题。所有这一切都可以使用内联 Javascript 正常工作......您只需将鼠标从图像移动到相邻的打开抽屉而不触发关闭它的功能......就好像抽屉的内联“鼠标输入”取消了图像的“鼠标离开”。

有什么建议么?

谢谢!


编辑:

我相信我在从图像传递到抽屉时使用 .stop(true, false) 解决了这个问题。这甚至在动画开始之前就停止了动画。然后在启动正常动画之前进入图像时也是如此......这具有停止由离开抽屉并进入图像而触发的动画的效果,但在正常进入图像时也什么都不做。更多测试,然后我将发布一些示例代码。


编辑#2:

我让它使用“stop()”和“delay()”来控制动画,但如果你可以让鼠标更快地进入抽屉,它可以冻结抽屉的打开。安装时间为 150 毫秒。但现在设置为 300 毫秒以夸大问题。

相关代码张贴在这里...

jsfiddle.net/qPLVp/8/


编辑#3:

多亏了 Neil,它现在运行得很好。通过更快的动画速度,鼠标越过菜单图像并进入抽屉的情况将保持在最低限度。但是如果发生这种情况,抽屉将不会关闭,这比从鼠标下方关闭要好得多。

http://jsfiddle.net/elusien/PayFw/8/


编辑#4:

再次感谢 Neil,这是相同代码的更高效版本......

http://jsfiddle.net/PayFw/9/

4

5 回答 5

1

活泼的,

我想出了一种不同的做事方式。基本上在“按钮”和“描述”上放置一个透明蒙版,并在其上使用“mouseleave”事件。

HTML:

<body>
<div id="Container" class="menuContainer" style="position: relative">
<div id="menumask">&nbsp;</div>
<!-- this simulates the menu rollover image -->
<div id="menuitem" style="position:absolute; background-color:#ff00ff; top:10px; width:200px; height:50px; text-align:center;">
    <b>MENU ITEM</b>
</div>

<!-- this is the drawer -->
    <div id="menu" class="menuContent">
        <br/>
        <p>Content of the menu drawer.</p>
        <br/>
        <p>Bla bla bla </p>
        <br/>
        <p>Bla bla bla Bla.</p>
        <br/>
        <p>Bla bla bla Bla bla.</p>
        <br/>
        <p>Bla bla bla Bla bla bla Bla bla.</p>
    </div>

Javascript:

$(document).ready(function() {
    $('#menuitem').bind('mouseenter', enter);
    $('#menumask').bind('mouseleave', leave);

    $('#menu').css({
        height: '500px',
        position: 'absolute',
        paddingTop: '50px',
        width: '200px',
        backgroundColor: '#080',
        zIndex: -1
    }).hide();
    $('#menumask').css({
        height: '550px',
        width: '200px',
        opacity: 0.99,
        position: 'absolute',
        fontSize: '20000px',
        overflow: 'hidden',
        zIndex: 2
    }).hide();

    function enter(){
        $('#menumask').show();
        $('#menu').stop(true,true).animate({height: 500}, 'slow');
    };
    function leave(){
        $('#menumask').hide();
        $('#menu').stop(true,true).slideUp({height:   0}, 'slow');};  
});

您可以将其用作菜单系统的基础。

问候尼尔

于 2011-02-09T19:24:06.883 回答
1

我已经修改了您的 jsFiddle 代码以使其正常工作。基本上我已将数据对象附加到您的#menu元素。当您打开此抽屉时,对象是{opening: true}。当抽屉完全打开(动画完成)时,对象是{opening: false}. 当你进入抽屉时我会检查这个,如果它是假的,我会停止动画。如果是真的,我不会停止动画。

代码是:

    function enter(event) { // mouseenter IMG
        // removed image rollover code

        $('#menu').data({opening: true}).stop(true, false).animate({
            top: '0',
            opacity: 1
        },{
            duration: 300  // slow the opening of the drawer
        },
        function(){$(this).data({opening: false});}
        );
    };
    function leave(event) { // mouseout IMG
        // removed image rollover code

        $('#menu').delay(400).animate({
            top: '-'+$ht+'px',
            opacity: 0
        },{
            duration: 600
        });
    };

    $('#menu').hover(
        function (){ // mouseenter Menu drawer
            if (!$(this).data('opening')) {
                $(this).stop(true, false);
            }
        },
        function (){ // mouseout Menu drawer
            $(this).delay(400).animate({
                top: '-'+$ht+'px',
                opacity: 0
            },{
                duration: 600    
            });

       }
   );

这现在工作正常。鉴于此,您可能想重做一些“延迟”。

于 2011-02-07T15:06:31.130 回答
0

您似乎正在寻找 .delegate() 函数,它将处理程序附加到现在或将来的 DOM 事件:

$(".menuItem").delegate(".subMenu","hover", function(){ $(this).show(); });

您可以在此处阅读有关 .delegate() 函数及其伙伴 .live() 的更多信息:http: //api.jquery.com/delegate/

于 2011-02-06T21:03:17.517 回答
0

如果没有看到代码,很难知道以下是否可行:

hover()将 2 个函数作为其参数,第一个在您输入图像时执行,第二个;当你离开图像。

您可能已将第二个功能设置为隐藏(关闭)抽屉。我会在之前添加一个小的延迟(例如delay(100)hide()并在抽屉本身上设置一个悬停事件以(在第一个函数参数中)停止动画队列stop(true, true)- 这将停止关闭抽屉,并在第二个函数中 - 关闭抽屉当你退出它。

于 2011-02-06T21:12:23.787 回答
0

嘿,我在尝试完成同样的事情时偶然发现了这篇文章。我想我可能会离开我的解决方案,因为它现在是 2017 年,.delegate已被弃用,并且使用数据来跟踪转换是否仍然有效似乎很混乱。

关键是使用传递给mouseleave回调的元素来获取element.relatedTarget.

$('.myMouseoverElements').on('mouseover', function() {        

  activeElements = $('.elements.to.open')
  activeElements.addClass('open')

  activeElements.on('mouseleave', function(element) {

    var sustainElements = $('.elements.to.sustain.mouseover')
    var drawerShouldClose = !$(element.relatedTarget).is(sustainElements)

    if (drawerShouldClose) {
      activeElements.removeClass("open")
      activeElements.off("mouseleave")
    }
  })
})

谢谢您的帮助!

于 2017-04-30T09:04:02.727 回答