jQuery:如何相对于另一个元素定位/动画绝对定位的元素

时间:2012-11-30 01:57:33

标签: jquery menu css-position

所以,我正在尝试创建一个包含导航项堆栈(行)的垂直导航菜单。当选择其中一行时,我希望菜单从上方(和下方)滑出,并且当此子菜单的顶部到达单击的行的底部时。这些子菜单还应具有一个起始位置,其中子菜单底部等于相关的导航项目底部,以便在向下动画时,它立即可见。

这个定位,停止点和起点,可以在这个小提琴中看到 - > http://jsfiddle.net/pGfCX/57/。请注意起点和终点。小提琴的其余部分由于位置的性质而被打破:相对。

我认为z-index可以修复后续导航项的推送(正如你可以在刚刚联系的小提琴中看到的那样)......但是这似乎不起作用。它看起来只有位置:绝对会启用正确的重叠(即子菜单隐藏在它上面的元素下面并覆盖它下面的元素)。不幸的是,这也有它的缺点。正如你在这个小提琴中看到的那样:http://jsfiddle.net/pGfCX/60/。您会注意到起始位置和结束位置始终相同,因为我每次都使用相同的类。虽然我可以将每个子菜单专门定位为它自己的唯一ID,但这样效率很低,难以维护。

实际上,我需要两种方法的混合......开始/结束位置的相对定位和绝对能够正确重叠。

希望这有道理......我真的需要帮助。我坚持使用这两种方法而且都没有工作。这令人沮丧。

这是我当前的jQuery代码:

$('.row').click(function() {

    // make all siblings AFTER row clicked get this class to reduce z-index and allow the menu to display above these rows (while still remaining below the rows above)

    $(this).nextAll().addClass('rowZ');
    $(this).next('.menu').show()
    $(this).next('.menu').animate({'top':'0'});

});

// when menu is out, the row clicked is the header row, upon clicking this, the related menu (and by default, all subsequent menus within) animate back up and hide

$('.rowHead').click(function() {

    $(this).next('.menu').animate({'top':'-100%'});
    $(this).next('.menu').hide();

});

非常感谢任何和所有帮助。谢谢!

编辑* 导航项目中的新方法...菜单,允许其具有绝对定位并相对于导航项目。然而,z-index似乎是关闭的(即它在动画项目(它的父项)之上设置动画,尽管z-index会暗示:

http://jsfiddle.net/pGfCX/81/

2 个答案:

答案 0 :(得分:1)

编辑:回到这个版本,因为虽然这不是一个答案,但最好还是作为一个类似的选择。

http://jsfiddle.net/pGfCX/70/

这似乎正如您所愿。保持相对定位,修复你的z索引,并给.row一个背景颜色:)我无休止地困惑我,因为我的z-index看起来很破碎,但这是因为元素正在下去.row(你可以在顶部看到文字) ),但因为它在容器上有灰色背景,看起来好像它不在行后面。应该是纯CSS修复:

#container{
    background:grey;
    width:100px;
    height:100%;
    position:relative;
    top:0;
    left:0;
    z-index:1;
}
.row{
    width:100px;
    height:40px;
    cursor:pointer;
    position:relative;
    z-index:1100;
    background-color: pink;
}
 .row:hover{
    background:red;
}
.menu{
    background:yellow;
    width:100px;
    height:300px;
    position:relative;
    top:-100%;
    left:0;
    z-index:2;
    display:none;
}
.menu .row {
    z-index: 10;   
}

答案 1 :(得分:0)

如果您没有为那些绝对定位的top元素设置.menu规则,它们会直接挂在每个元素前面相对定位的.row元素下面,而不是浮动到#container的顶部。然后,您可以使用jQuery的slideDown()slideUp()动画来显示/隐藏菜单中所需的位置。

jsFiddle

Working Example

示例代码

CSS

#container {
    background:#666;
    width:100px;
    height:100%;
    position:fixed;
    top:0;
    left:0;
   z-index: 10;
}
.row {
    width:100px;
    height:40px;
    cursor:pointer;
    position:relative;
    z-index:1;
    line-height: 40px;
    vertical-align: middle;
    text-align: center;
    box-shadow: inset 0px 40px 40px -40px #fff;
}
.row:hover {
    background:red;
}
.row.active {
    background: #333;
    color: #fff;
}    
.menu {
    background: #999;
    width:100px;
    height:auto;
    position:absolute;
    left:0;
    z-index: 2;
    display:none;
    box-shadow: 0px 4px 1px rgba(0,0,0,0.3);
}

JS

$('.menu').prev('.row').click(function() {

    // Stops the handler from firing if an animation is in progress
    if (!$('#container').is('.working')) {

        // Begin manipulating the menu...
        $('#container').addClass('working');

        // Defines how fast menus will slide up/down
        var slideSpeed = 200;    

        // If menus need to be hidden, wait for them to slide up, otherwise, don't bother
        var d = ($(this).parent().children('.row.active').length > 0) ? slideSpeed : 0;

        // IF this rowhead is collapsed, expand it and collapse expanded siblings
        if (!$(this).is('.active')) {

// Collapse the active menu at this level, if any             
            $(this).siblings('.row.active').removeClass('active').next('.menu').slideUp(d, function(){
             // When this menu is hidden, collapse all expanded submenus
             $(this).find('.row').removeClass('active');
             $(this).find('.menu').hide();
        });

        // Expand this menu after others have finished collapsing
        window.setTimeout(function(a){

            // Fallback for bodyless rowheads: skips wait if this rowhead has no menu
            b = ($(a).parent().find('.row.active').length > 0) ? slideSpeed : 0;

            // Expand this menu
            $(a).addClass('active').next('.menu').slideDown(slideSpeed, function(){
                // Ready container for more interaction after menu (if any) expands 
                $('#container').removeClass('working');            
            });
        },d,this);
    }

    // Otherwise, if this menu is expanded, collapse it                          
    else $(this).removeClass('active').next('.menu').slideUp(d, function(){ 

         // When this menu is hidden, collapse all expanded submenus
         $(this).find('.row').removeClass('active');
         $(this).find('.menu').hide();

         //Ready the container for more interaction        
         $('#container').removeClass('working');
        });
    }
});