Javascript 隐藏在其他元素后面的引导下拉菜单

Javascript 隐藏在其他元素后面的引导下拉菜单,javascript,html,css,twitter-bootstrap,Javascript,Html,Css,Twitter Bootstrap,我有一个类似的问题。但那里的解决方案对我的问题不起作用。讨论已经结束,等待进一步的建议。 不幸的是,我不能完全按照JSFIDLE上的代码显示代码。然而,问题是这样的。尝试在第一个面板区域内展开下拉列表时,下拉列表隐藏在其他元素后面。 我花了好几个小时尝试关于“堆叠上下文”、“位置”和“z索引”的不同建议。 如果有人能给我指点任何有帮助的资源,我将不胜感激 <div class="btn-group"> <button type="butt

我有一个类似的问题。但那里的解决方案对我的问题不起作用。讨论已经结束,等待进一步的建议。 不幸的是,我不能完全按照JSFIDLE上的代码显示代码。然而,问题是这样的。尝试在第一个面板区域内展开下拉列表时,下拉列表隐藏在其他元素后面。 我花了好几个小时尝试关于“堆叠上下文”、“位置”和“z索引”的不同建议。 如果有人能给我指点任何有帮助的资源,我将不胜感激

<div class="btn-group">
                    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> <span data-bind="label">Select One</span>&nbsp;<span class="caret"></span>

                    </button>
                    <ul class="dropdown-menu" role="menu">
                        <li><a href="#">Item 1</a>
                        </li>
                        <li><a href="#">Another item</a>
                        </li>
                        <li><a href="#">This is a longer item that will not fit properly</a>
                        </li>
                    </ul>
                </div>

选择一个

您有两个选择。通过将父级css设置为“overflow:auto”,可以使容器的溢出扩展以适合内容

.panel-body { /* parent container of the menu */
    overflow:auto;
}
(function() {
  // hold onto the drop down menu                                             
  var dropdownMenu;

  // and when you show it, move it to the body                                     
  $(window).on('show.bs.dropdown', function(e) {

    // grab the menu        
    dropdownMenu = $(e.target).find('.dropdown-menu');

    // detach it and append it to the body
    $('body').append(dropdownMenu.detach());   

    // grab the new offset position
    var eOffset = $(e.target).offset();

    // make sure to place it where it would normally go (this could be improved)
    dropdownMenu.css({
        'display': 'block',
        'top': eOffset.top + $(e.target).outerHeight(),
        'left': eOffset.left
    });                                                
  });

  // and when you hide it, reattach the drop down, and hide it normally                                                   
  $(window).on('hide.bs.dropdown', function(e) {        
    $(e.target).append(dropdownMenu.detach());        
    dropdownMenu.hide();                              
  });                                                   
})(); 
dropdown-menu {}
或者,您可以使用JavaScript在功能上处理菜单位置。此选项有点“黑客”,需要进一步改进。您需要改进它以处理在同一页面上同时打开的多个菜单,并且需要改进它选择菜单的方式。您可能还希望添加滚动支持,以移动带有目标元素的菜单,除非这不是问题。这是小提琴:

.panel-body { /* parent container of the menu */
    overflow:auto;
}
(function() {
  // hold onto the drop down menu                                             
  var dropdownMenu;

  // and when you show it, move it to the body                                     
  $(window).on('show.bs.dropdown', function(e) {

    // grab the menu        
    dropdownMenu = $(e.target).find('.dropdown-menu');

    // detach it and append it to the body
    $('body').append(dropdownMenu.detach());   

    // grab the new offset position
    var eOffset = $(e.target).offset();

    // make sure to place it where it would normally go (this could be improved)
    dropdownMenu.css({
        'display': 'block',
        'top': eOffset.top + $(e.target).outerHeight(),
        'left': eOffset.left
    });                                                
  });

  // and when you hide it, reattach the drop down, and hide it normally                                                   
  $(window).on('hide.bs.dropdown', function(e) {        
    $(e.target).append(dropdownMenu.detach());        
    dropdownMenu.hide();                              
  });                                                   
})(); 
dropdown-menu {}
也许有更好的方法可以做到这一点,但概念是将菜单从父元素的范围移动到主体。当您依赖html数据属性来设置菜单时,您将很难做到这一点,但这正是我引用的第二个解决方案变得有用的地方

遗憾的是,我建议研究bootstrap提供的“Via Javascript”选项,但显然他们没有设置目标append元素的选项。如果有一个选项可以将菜单附加到任何您想要的元素上,就像它们的大多数其他项目一样:

.panel-body { /* parent container of the menu */
    overflow:auto;
}
(function() {
  // hold onto the drop down menu                                             
  var dropdownMenu;

  // and when you show it, move it to the body                                     
  $(window).on('show.bs.dropdown', function(e) {

    // grab the menu        
    dropdownMenu = $(e.target).find('.dropdown-menu');

    // detach it and append it to the body
    $('body').append(dropdownMenu.detach());   

    // grab the new offset position
    var eOffset = $(e.target).offset();

    // make sure to place it where it would normally go (this could be improved)
    dropdownMenu.css({
        'display': 'block',
        'top': eOffset.top + $(e.target).outerHeight(),
        'left': eOffset.left
    });                                                
  });

  // and when you hide it, reattach the drop down, and hide it normally                                                   
  $(window).on('hide.bs.dropdown', function(e) {        
    $(e.target).append(dropdownMenu.detach());        
    dropdownMenu.hide();                              
  });                                                   
})(); 
dropdown-menu {}

编辑

正如@Andrea Pizzirani提到的,您可以尝试删除菜单绝对位置的css,但我不推荐这样做!这将打乱菜单的所有其他实例,除非您添加其他css以限制更改的范围。另外,如果你想把菜单放在按钮下面,你必须重做引导程序已经准备好的CSS

尽管如此,如果它能工作,并且你不担心弄乱所有其他菜单,那么它可能就是你正在寻找的解决方案。这里有一把小提琴演示了解决方案:

.panel-body { /* parent container of the menu */
    overflow:auto;
}
(function() {
  // hold onto the drop down menu                                             
  var dropdownMenu;

  // and when you show it, move it to the body                                     
  $(window).on('show.bs.dropdown', function(e) {

    // grab the menu        
    dropdownMenu = $(e.target).find('.dropdown-menu');

    // detach it and append it to the body
    $('body').append(dropdownMenu.detach());   

    // grab the new offset position
    var eOffset = $(e.target).offset();

    // make sure to place it where it would normally go (this could be improved)
    dropdownMenu.css({
        'display': 'block',
        'top': eOffset.top + $(e.target).outerHeight(),
        'left': eOffset.left
    });                                                
  });

  // and when you hide it, reattach the drop down, and hide it normally                                                   
  $(window).on('hide.bs.dropdown', function(e) {        
    $(e.target).append(dropdownMenu.detach());        
    dropdownMenu.hide();                              
  });                                                   
})(); 
dropdown-menu {}

编辑
我终于找到了我最初找到这个解决方案的地方。必须在

尝试删除位置时给予信任:绝对来自:

dropdown-menu {}
然后通过css将菜单置于按钮下方。

您只需添加:

.panel.panel-default{
      overflow: inherit !important;
    }

我在你的第一把小提琴(Chrome v.45)中看不到整个下拉列表,是吗?然而,JS的第二个解决方案正在发挥作用。非常感谢您花费的时间和精力。是的,第一个解决方案只允许父容器展开,以便您可以滚动查看下拉列表的其余部分。但是我很高兴JS版本适合你!我可能说得太早了——这无论如何都不是万灵药。由于它将菜单从正常的文档流中删除,任何依赖于该结构的jQuery插件都将被破坏。@BrucePierson如果您能想出更好的解决方案,请告诉我!我只是发布了一个答案,因为这个问题很有趣。流量从一开始就是个问题,因此注意到操纵流量会产生副作用是一个非常恰当的观察。感谢您注意到,它很可能会影响其他jQuery插件,具体取决于下拉菜单的流程。@Jonathan nothing-Bootstrap将其标记为will not fix,因为这确实是一个popper.js问题。我已经研究了一些问题,但在表格单元格中找不到弹出菜单的答案。顺便说一下,它只影响div中具有
table responsive
类的表。如果删除此选项,它会起作用,但当然会使表溢出视口
.panel-body { /* parent container of the menu */
    overflow:auto;
}
(function() {
  // hold onto the drop down menu                                             
  var dropdownMenu;

  // and when you show it, move it to the body                                     
  $(window).on('show.bs.dropdown', function(e) {

    // grab the menu        
    dropdownMenu = $(e.target).find('.dropdown-menu');

    // detach it and append it to the body
    $('body').append(dropdownMenu.detach());   

    // grab the new offset position
    var eOffset = $(e.target).offset();

    // make sure to place it where it would normally go (this could be improved)
    dropdownMenu.css({
        'display': 'block',
        'top': eOffset.top + $(e.target).outerHeight(),
        'left': eOffset.left
    });                                                
  });

  // and when you hide it, reattach the drop down, and hide it normally                                                   
  $(window).on('hide.bs.dropdown', function(e) {        
    $(e.target).append(dropdownMenu.detach());        
    dropdownMenu.hide();                              
  });                                                   
})(); 
dropdown-menu {}