jQuery滑动抽屉菜单阻止其他内容

时间:2011-10-02 18:54:53

标签: jquery css jquery-animate drop-down-menu

我的工作菜单(有一个小问题)......

我有一个滑动抽屉菜单系统,我已经成功使用了很长一段时间。它使用翻转图像,下面这个工作jsFiddle (#1)很好地演示了静态div代替图像翻转的相关操作。

我的系统使用容器div,每个容器overflow:hidden;和抽屉div。当jQuery动画将抽屉滑动到容器外时,它会自动隐藏。当您将鼠标从抽屉移回菜单时,可以使用各种其他技术来停止动画,以防止抽屉过早关闭。

在SO社区的帮助下,这个系统投入了大量的时间和精力。它很适合我,但现在菜单抽屉包含更多内容。更大/更长的抽屉已经揭示了这个新问题,我将在下面描述。

出于演示目的,我已经概述了容器以显示其位置并减慢动画。最终项目更快,没有这些大纲。

#1 - http://jsfiddle.net/PayFw/143/

正如您所看到的,当需要交互的内容(例如链接)被这些容器隐藏或部分阻止时,该链接在覆盖时不可点击。这个问题可以在Mozilla和Webkit中看到,但不能在IE-8中看到。 (在这种情况下,我认为IE它没有按预期工作。)我没有测试过其他版本。

使用z-index不是解决方案,因为这只会导致抽屉在内容后面滑动。显然,我希望抽屉在使用时滑过内容。


我一直在努力......

上述小问题的各种解决方案似乎只会导致更复杂的问题。

我认为这个很简单......只需用visibility:hidden;更改容器是不可见的。然后,当您将鼠标悬停以调用滑动抽屉时,请在抽屉关闭后更改为visibility:visible;并返回visibility:hidden;。即使增加了动画的复杂性,也可以使用回调来完成关闭动画,然后再使容器不可见。

当您“干净地”输入菜单项(“干净地”定义:从顶部/底部而不触及相邻的菜单项时),它工作得非常好。

然而,这个解决方案创造了一个全新的问题。当您从一个菜单项移动到另一个菜单项时,jQuery动画stop()会干扰下一个菜单的打开,并在您仍然悬停时将其关闭。它使回调函数变得不可靠....有时,正如你可以通过灰色轮廓看到的那样,容器可见,从而破坏了这个解决方案的整个目的。

#2 - http://jsfiddle.net/PayFw/144/


问题:

  1. 是否还有另一种方法可以防止system #1在抽屉关闭时始终阻止内容?

  2. 如果没有,有没有办法解决version #2的问题? ie - 使用抽屉动画正确切换容器的可见性,同时保持与version #1中相同的清洁/可靠操作。

  3. 如果没有简单或实用的解决方案,是否有一个可以轻松与我的系统集成的jQuery插件?如果是这样,哪一个又如何?我知道有很多jQuery菜单抽屉系统,但我需要一些可以在我的已经存在的图像翻转下放置可自定义的滑动抽屉(同时不会阻止可能属于任何内容的任何内容的点击能力)抽屉的操作区域。


  4. 修改

    关于 vzwick 发布的答案:他的解决方案简单明了但需要进一步解释。他关于使用display:none;& display:block;取代visibility:hidden;& visibility:visible;只是故事的一部分。

    我在容器上使用visibility:hidden;

    相反,我应该在抽屉上使用display:none;

    为什么?

    通过切换visibility:hidden;容器会保留在内容流中。容器位于流量范围内,其自动尺寸由抽屉尺寸决定。

    通过切换display:none;抽屉将从内容流中移除。通过从流动中移除抽屉,其容器变为零尺寸。因此,虽然容器仍在内容流中,但它们是折叠的,零大小,不再干扰页面内容,因此不再需要使它们不可见。

    http://jsfiddle.net/PayFw/146/

    辉煌。感谢 vzwick

1 个答案:

答案 0 :(得分:1)

使用display:block和display:none分别可以轻松修复问题:

$('div[id|="m"]').each(function (i) {

    $(this).hover(enter, leave);

    $ht[i] = ($('#menu-'+i).height());
    $('#menu-'+i).css({
        'top': '-'+$ht[i]+'px',
        'display': 'none' // <--- changed
    });

});

function enter() { 
     j = $(this).attr('id').replace(/m-/, "");
     $('#menu-'+j).data({closing: false}).stop(true, false).animate({top: '0'},800).css({'display' : 'block'}); // <--- changed
};

function leave() { 
     $('#menu-'+j).data({closing: true}).delay(100).animate({top: '-'+$ht[j]+'px'},800, function(){ $(this).css({'display' : 'none'}) }); // <--- changed
};

有关工作示例,请参阅this fiddle

修改

澄清:

visibility属性设置为hidden基本上只是说opacity:0的另一种方式。该元素仍然在盒子模型中保留其尺寸和位置。在您的情况下,这意味着它覆盖了其他内容。

相比之下,display属性设置为none时,会从框模型/流中完全删除元素。