多个模态叠加

Wil*_*rai 171 javascript jquery modal-dialog twitter-bootstrap twitter-bootstrap-3

我需要叠加显示在第一个模态上方,而不是在后面.

模态覆盖背后

$('#openBtn').click(function(){
	$('#myModal').modal({show:true})
});
Run Code Online (Sandbox Code Playgroud)
<a data-toggle="modal" href="#myModal" class="btn btn-primary">Launch modal</a>

<div class="modal" id="myModal">
	<div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
          <h4 class="modal-title">Modal title</h4>
        </div><div class="container"></div>
        <div class="modal-body">
          Content for the dialog / modal goes here.
          <br>
          <br>
          <br>
          <br>
          <br>
          <a data-toggle="modal" href="#myModal2" class="btn btn-primary">Launch modal</a>
        </div>
        <div class="modal-footer">
          <a href="#" data-dismiss="modal" class="btn">Close</a>
          <a href="#" class="btn btn-primary">Save changes</a>
        </div>
      </div>
    </div>
</div>
<div class="modal" id="myModal2" data-backdrop="static">
	<div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
          <h4 class="modal-title">Second Modal title</h4>
        </div><div class="container"></div>
        <div class="modal-body">
          Content for the dialog / modal goes here.
        </div>
        <div class="modal-footer">
          <a href="#" data-dismiss="modal" class="btn">Close</a>
          <a href="#" class="btn btn-primary">Save changes</a>
        </div>
      </div>
    </div>
</div>


<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/js/bootstrap.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

我试图改变z-index.modal-backdrop,但它成了一个烂摊子.

在某些情况下,我在同一页面上有两个以上的模态.

A1r*_*Pun 391

在看到许多针对此的修复之后,并没有一个完全符合我的需要,我想出了一个更短的解决方案,其灵感来自@YermoLamers和@Ketwaroo.

背景z-index修复
此解决方案使用a,setTimeout因为触发.modal-backdrop事件时不会创建show.bs.modal.

$(document).on('show.bs.modal', '.modal', function () {
    var zIndex = 1040 + (10 * $('.modal:visible').length);
    $(this).css('z-index', zIndex);
    setTimeout(function() {
        $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
    }, 0);
});
Run Code Online (Sandbox Code Playgroud)
  • 这适用于.modal页面上创建的每个(甚至是动态模态)
  • 背景立即覆盖以前的模态

示例jsfiddle

如果你因为任何原因不喜欢硬编码的z-index,你可以像这样计算页面上最高的z-index:

var zIndex = Math.max.apply(null, Array.prototype.map.call(document.querySelectorAll('*'), function(el) {
  return +el.style.zIndex;
})) + 10;
Run Code Online (Sandbox Code Playgroud)

滚动条修复
如果页面上的模态超出了浏览器高度,则在关闭第二个模式时无法滚动它.要修复此添加:

$(document).on('hidden.bs.modal', '.modal', function () {
    $('.modal:visible').length && $(document.body).addClass('modal-open');
});
Run Code Online (Sandbox Code Playgroud)

版本
此解决方案使用bootstrap 3.1.0 - 3.3.5进行测试

  • 与最新的 BS4 配合良好 (7认同)
  • 此方法似乎在BS4上正常工作 (3认同)
  • 为了使它与[bootstrap datepicker](https://bootstrap-datepicker.readthedocs.io/en/stable/)`var配合使用,我必须进行较小的更改(在第二行中添加了.not(this)`)。 zIndex = 1040 +(10 * $('。modal:visible')。not(this).length);` (2认同)
  • 你是个天才,这太不可思议了;如果我可以给你买啤酒,我会的;干杯。 (2认同)

Yer*_*ers 80

我意识到答案已经被接受,但我强烈建议不要黑客自举来解决这个问题.

您可以通过挂钩shown.bs.modal和hidden.bs.modal事件处理程序并在那里调整z-index来轻松实现相同的效果.

这是一个有效的例子

这里有更多信息.

此解决方案可自动使用任意深度堆栈模式.

脚本源代码:

$(document).ready(function() {

    $('.modal').on('hidden.bs.modal', function(event) {
        $(this).removeClass( 'fv-modal-stack' );
        $('body').data( 'fv_open_modals', $('body').data( 'fv_open_modals' ) - 1 );
    });

    $('.modal').on('shown.bs.modal', function (event) {
        // keep track of the number of open modals
        if ( typeof( $('body').data( 'fv_open_modals' ) ) == 'undefined' ) {
            $('body').data( 'fv_open_modals', 0 );
        }

        // if the z-index of this modal has been set, ignore.
        if ($(this).hasClass('fv-modal-stack')) {
            return;
        }

        $(this).addClass('fv-modal-stack');
        $('body').data('fv_open_modals', $('body').data('fv_open_modals' ) + 1 );
        $(this).css('z-index', 1040 + (10 * $('body').data('fv_open_modals' )));
        $('.modal-backdrop').not('.fv-modal-stack').css('z-index', 1039 + (10 * $('body').data('fv_open_modals')));
        $('.modal-backdrop').not('fv-modal-stack').addClass('fv-modal-stack'); 

    });        
});
Run Code Online (Sandbox Code Playgroud)

  • 我遇到的一个问题是当第一个模态显示并需要一个滚动条时,如果我显示第二个模态,它将删除第一个模态的滚动条并且我被一个剪切的模态卡住了.为了解决这个问题,我把它添加到我的CSS中,.modal {overflow-y:auto; } (4认同)
  • 很酷,但是当一个模态关闭时,会出现两个滚动条 - 一个用于模态,第二个用于整页.这可以解决吗? (3认同)
  • 要在close上处理额外的scoll bar,你需要在hidden.bs.modal监听器中向body添加类"modal-open". (3认同)
  • 我觉得这应该是公认的答案。对我来说完美无缺。 (2认同)

小智 23

根据Yermo Lamers的建议,这个更短的版本,这似乎工作正常.即使有基本的动画,如淡入/淡出,甚至疯狂的蝙蝠侠报纸旋转.http://jsfiddle.net/ketwaroo/mXy3E/

$('.modal').on('show.bs.modal', function(event) {
    var idx = $('.modal:visible').length;
    $(this).css('z-index', 1040 + (10 * idx));
});
$('.modal').on('shown.bs.modal', function(event) {
    var idx = ($('.modal:visible').length) -1; // raise backdrop after animation.
    $('.modal-backdrop').not('.stacked').css('z-index', 1039 + (10 * idx));
    $('.modal-backdrop').not('.stacked').addClass('stacked');
});
Run Code Online (Sandbox Code Playgroud)

  • 这里剩下的一个问题是,如果你关闭第二个模态并且你的页面有足够的文本超过浏览器大小,你最终会得到奇怪的滚动条行为.你还必须恢复body元素上的`modal-open`类:http://jsfiddle.net/vkyjocyn/ (7认同)

Sev*_*ins 21

结合A1rPun的回答和StriplingWarrior的建议,我提出了这个:

$(document).on({
    'show.bs.modal': function () {
        var zIndex = 1040 + (10 * $('.modal:visible').length);
        $(this).css('z-index', zIndex);
        setTimeout(function() {
            $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
        }, 0);
    },
    'hidden.bs.modal': function() {
        if ($('.modal:visible').length > 0) {
            // restore the modal-open class to the body element, so that scrolling works
            // properly after de-stacking a modal.
            setTimeout(function() {
                $(document.body).addClass('modal-open');
            }, 0);
        }
    }
}, '.modal');
Run Code Online (Sandbox Code Playgroud)

甚至可以用于事后添加的动态模态,并删除第二个滚动条问题.我发现这个最有用的东西是将模态中的表单与来自Bootbox警报的验证反馈集成,因为那些使用动态模态,因此需要将事件绑定到文档而不是.modal,因为它只将它附加到现有情态动词.

在这里小提琴

  • 我建议使用开放模态的max z索引来确定基本z-index而不是硬编码值1040?http://stackoverflow.com/a/5680815/2569159 (2认同)

小智 11

我创建了一个Bootstrap插件,其中包含了很多这里发布的想法.

Bootply上的演示:http://www.bootply.com/cObcYInvpq

Github:https://github.com/jhaygt/bootstrap-multimodal

它还解决了连续模态的问题,导致背景变得更暗和更暗.这可确保在任何给定时间只能看到一个背景:

if(modalIndex > 0)
    $('.modal-backdrop').not(':first').addClass('hidden');
Run Code Online (Sandbox Code Playgroud)

可见背景的z-index在show.bs.modalhidden.bs.modal事件上都会更新:

$('.modal-backdrop:first').css('z-index', MultiModal.BASE_ZINDEX + (modalIndex * 20));
Run Code Online (Sandbox Code Playgroud)


Bas*_*sen 10

当解决堆栈模式时,在关闭一个主页面时,我发现较新版本的Bootstrap(至少从版本3.0.3开始)不需要任何额外的代码来堆叠模态.

您可以在页面中添加多个模式(当然具有不同的ID).打开多个模态时发现的唯一问题是关闭一个删除modal-open主体选择器的类.

您可以使用以下Javascript代码重新添加modal-open:

$('.modal').on('hidden.bs.modal', function (e) {
    if($('.modal').hasClass('in')) {
    $('body').addClass('modal-open');
    }    
});
Run Code Online (Sandbox Code Playgroud)

如果您不需要叠加模式的背景效果,则可以进行设置data-backdrop="false".

版本3.1.1.修复修复模态背景覆盖模态的滚动条,但上述解决方案似乎也适用于早期版本.


Ric*_*las 10

Bootstrap 4.5 的简单解决方案

.modal.fade {
  background: rgba(0, 0, 0, 0.5);
}

.modal-backdrop.fade {
  opacity: 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 我将您的CSS与JavaScript修复结合起来,解决了引导多模式不滚动问题https://github.com/nakupanda/bootstrap3-dialog/issues/70#issuecomment-721108599,stackOverflow问题:https://stackoverflow.com/a/ 64662694/423356 (3认同)
  • 哇,这太简单了!Bootstrap 团队真的应该使用这个! (3认同)
  • 该解决方案也适用于 Bootstrap 5。谢谢里卡多! (2认同)

mic*_*czy 9

如果您正在寻找 Bootstrap 4 解决方案,那么使用纯 CSS 有一个简单的解决方案:

.modal.fade {
    background: rgba(0,0,0,0.5);
}
Run Code Online (Sandbox Code Playgroud)

  • 这似乎运作良好......您认为这将是标准的 Bootstrap? (2认同)

Wil*_*rai 8

终于解决了.我在很多方面测试它并且工作正常.

以下是具有相同问题的任何人的解决方案:更改Modal.prototype.show函数(在bootstrap.js或modal.js)

从:

if (transition) {
   that.$element[0].offsetWidth // force reflow
}   

that.$element
   .addClass('in')
   .attr('aria-hidden', false)

that.enforceFocus()
Run Code Online (Sandbox Code Playgroud)

至:

if (transition) {
    that.$element[0].offsetWidth // force reflow
}

that.$backdrop
   .css("z-index", (1030 + (10 * $(".modal.fade.in").length)))

that.$element
   .css("z-index", (1040 + (10 * $(".modal.fade.in").length)))
   .addClass('in')
   .attr('aria-hidden', false)

that.enforceFocus()
Run Code Online (Sandbox Code Playgroud)

这是我找到的最佳方式:检查打开了多少个模态,并将模态和背景的z-index更改为更高的值.


Tim*_*ber 5

尝试将以下内容添加到 bootply 上的 JS 中

$('#myModal2').on('show.bs.modal', function () {  
$('#myModal').css('z-index', 1030); })

$('#myModal2').on('hidden.bs.modal', function () {  
$('#myModal').css('z-index', 1040); })
Run Code Online (Sandbox Code Playgroud)

解释:

在尝试了这些属性(使用 Chrome 的开发工具)后,我意识到z-index下面的任何值1031都会将事物置于背景后面。

因此,通过使用引导程序的模态事件句柄,我将其设置z-index1030。如果#myModal2显示,则将z-index后面设置为1040如果#myModal2隐藏。

演示