jQuery 多模态叠加

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19305821/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 23:38:04  来源:igfitidea点击:

Multiple modals overlay

javascriptjquerytwitter-bootstraptwitter-bootstrap-3modal-dialog

提问by Willian Bonho Daiprai

I need that the overlay shows above the first modal, not in the back.

我需要覆盖显示在第一个模态上方,而不是在后面。

Modal overlay behind

后面的模态叠加

$('#openBtn').click(function(){
 $('#myModal').modal({show:true})
});
<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>

I tried to change the z-indexof .modal-backdrop, but it becomes a mess.

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

In some cases I have more than two modals on the same page.

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

回答by A1rPun

After seeing many fixes for this, and none of them were exactly what I needed I've came up with a even shorter solution that is inspired by @YermoLamers& @Ketwaroo.

在看到了许多针对此问题的修复程序,但没有一个正是我所需要的,我想出了一个更短的解决方案,其灵感来自@YermoLamers和 @Ketwaroo。

Backdrop z-index fix
This solution uses a setTimeoutbecause the .modal-backdropisn't created when the event show.bs.modalis triggered.

背景 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);
});
  • This works for every .modalcreated on the page (even dynamic modals)
  • The backdrop instantly overlays the previous modal
  • 这适用于.modal页面上创建的每个(甚至动态模态)
  • 背景立即覆盖了之前的模态

Example jsfiddle

示例 jsfiddle

If you don't like the hardcoded z-index for any reason you can calculate the highest z-indexon the page like this:

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

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

Scrollbar fix
If you have a modal on your page that exceeds the browser height, then you can't scroll in it when closing an second modal. To fix this add:

滚动条修复
如果页面上的模态超过浏览器高度,则在关闭第二个模态时将无法在其中滚动。要解决此问题,请添加:

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

Versions
This solution is tested with bootstrap 3.1.0 - 3.3.5

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

回答by Yermo Lamers

I realize an answer has been accepted, but I strongly suggest not hacking bootstrap to fix this.

我意识到一个答案已被接受,但我强烈建议不要破解引导程序来解决这个问题。

You can pretty easily achieve the same effect by hooking the shown.bs.modal and hidden.bs.modal event handlers and adjusting the z-index there.

你可以很容易地通过挂钩showed.bs.modal 和hidden.bs.modal 事件处理程序并在那里调整z-index 来实现相同的效果。

Here's a working example

这是一个工作示例

A bit more info is available here.

此处提供更多信息

This solution works automatically with arbitrarily deeply stacks modals.

此解决方案可自动与任意深度堆叠的模态一起使用。

The script source code:

脚本源代码:

$(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'); 

    });        
});

回答by Ketwaroo D. Yaasir

Something shorter version based off Yermo Lamers' suggestion, this seems to work alright. Even with basic animations like fade in/out and even crazy batman newspaper rotate. http://jsfiddle.net/ketwaroo/mXy3E/

根据 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');
});

回答by Seven Deadly Sins

Combining A1rPun's answer with the suggestion by StriplingWarrior, I came up with this:

结合 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');

Works even for dynamic modals added after the fact, and removes the second-scrollbar issue. The most notable thing that I found this useful for was integrating forms inside modals with validation feedback from Bootbox alerts, since those use dynamic modals and thus require you to bind the event to document rather than to .modal, since that only attaches it to existing modals.

甚至适用于事后添加的动态模态,并消除了第二个滚动条问题。我发现这很有用的最值得注意的事情是将模态内的表单与来自 Bootbox 警报的验证反馈集成在一起,因为它们使用动态模态,因此需要您将事件绑定到文档而不是 .modal,因为这只会将它附加到现有的模态。

Fiddle here.

在这里摆弄。

回答by jhay

I created a Bootstrap plugin that incorporates a lot of the ideas posted here.

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

Demo on Bootply: http://www.bootply.com/cObcYInvpq

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

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

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

It also addresses the issue with successive modals causing the backdrop to become darker and darker. This ensures that only one backdrop is visible at any given time:

它还解决了连续模态导致背景变得越来越暗的问题。这确保在任何给定时间只有一个背景是可见的:

if(modalIndex > 0)
    $('.modal-backdrop').not(':first').addClass('hidden');

The z-index of the visible backdrop is updated on both the show.bs.modaland hidden.bs.modalevents:

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

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

回答by Bass Jobsen

When solving Stacking modals scrolls the main page when one is closedi found that newer versions of Bootstrap (at least since version 3.0.3) do not require any additional code to stack modals.

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

You can add more than one modal (of course having a different ID) to your page. The only issue found when opening more than one modal will be that closing one remove the modal-openclass for the body selector.

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

You can use the following Javascript code to re-add the modal-open:

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

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

In the case that do not need the backdrop effect for the stacked modal you can set data-backdrop="false".

在不需要堆叠模式的背景效果的情况下,您可以设置data-backdrop="false".

Version 3.1.1. fixed Fix modal backdrop overlaying the modal's scrollbar, but the above solution seems also to work with earlier versions.

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

回答by Willian Bonho Daiprai

Finally solved. I tested it in many ways and works fine.

终于解决了。我以多种方式对其进行了测试,并且运行良好。

Here is the solution for anyone that have the same problem: Change the Modal.prototype.showfunction (at bootstrap.js or modal.js)

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

FROM:

从:

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

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

that.enforceFocus()

TO:

到:

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()

It's the best way that i found: check how many modals are opened and change the z-index of the modal and the backdrop to a higher value.

这是我发现的最好方法:检查打开了多少模态并将模态和背景的 z-index 更改为更高的值。

回答by michal.jakubeczy

If you're looking for Bootstrap 4 solution, there's an easy one using pure CSS:

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

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

回答by Timber

Try adding the following to your JS on bootply

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

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

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

Explanation:

解释:

After playing around with the attributes(using Chrome's dev tool), I have realized that any z-indexvalue below 1031will put things behind the backdrop.

在玩弄属性后(使用 Chrome 的开发工具),我意识到z-index下面的任何值1031都会把东西放在背景后面。

So by using bootstrap's modal event handles I set the z-indexto 1030. If #myModal2is shown and set the z-indexback to 1040if #myModal2is hidden.

因此,通过使用自举的模态事件句柄我设置z-index1030。如果#myModal2显示并将z-index返回设置为1040如果#myModal2隐藏。

Demo

演示

回答by nuEn

Everytime you run sys.showModal function increment z-index and set it to your new modal.

每次运行 sys.showModal 函数都会增加 z-index 并将其设置为新的模态。

function system() {

    this.modalIndex = 2000;

    this.showModal = function (selector) {
        this.modalIndex++;

        $(selector).modal({
            backdrop: 'static',
            keyboard: true
        });
        $(selector).modal('show');
        $(selector).css('z-index', this.modalIndex );       
    }

}

var sys = new system();

sys.showModal('#myModal1');
sys.showModal('#myModal2');