【问题标题】:jQuery sliding drawer menu is blocking other contentjQuery滑动抽屉菜单阻止了其他内容
【发布时间】:2011-10-02 18:54:53
【问题描述】:

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

我有一个滑动抽屉菜单系统,我已经成功使用了一段时间。它使用翻转图像,下面这个有效的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 的问题?即 - 让容器的可见性与抽屉动画正确切换,同时保持与version #1 中相同的干净/可靠操作。

  3. 如果没有简单实用的解决方案,有没有可以轻松集成到我系统中的jQuery插件?如果是这样,是哪一个以及如何?我知道有大量的 jQuery 菜单抽屉系统,但我需要一些可以将可自定义的滑动抽屉放在我的已经存在的图像翻转下的东西(同时不会阻止任何可能落入抽屉的操作区域)。


编辑:

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

我在容器上使用visibility:hidden;

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

为什么?

通过切换visibility:hidden;容器 会停留在内容流中。容器在流程中,并具有由抽屉大小决定的自动大小。

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

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

太棒了。感谢 vzwick

【问题讨论】:

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


    【解决方案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 时,会从盒子模型/流中完全移除元素。

    【讨论】:

    • 是的,我完全理解display:none; 将元素从流中移除,而visibility:hidden; 只是使其不可见。您的方法很好,因为通过将display:none; 应用于抽屉,容器仍然存在,但它的小尺寸不是问题。很不错。谢谢!
    • 关于您的编辑...请参阅我的 OP 中的编辑。为了澄清起见,我将visibility:hidden 应用于容器。您使用display:none 的解决方案应用于抽屉。我的意思是,您的目标也是完全不同的元素。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-27
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多