Bootstrap: 在模态框中打开另一个模态框

124

所以,我正在使用这段代码在当前打开的模态窗口中打开另一个模态窗口:

<a onclick=\"$('#login').modal('hide');$('#lost').modal('show');\" href='#'>Click</a>

发生的情况是,大约500毫秒滚动条会重复。我猜是因为当前的模态框仍在淡出。然而,它看起来非常不平滑且卡顿。

我会感激任何解决此问题的建议。

此外,用onclick事件构建这种方式是否不专业?

我正在使用Bootstrap版本3.0。

编辑:我想缩短模态框淡出的时间。如何实现?


4
可以在http://www.bootply.com/lvKQA2AM28找到一个工作示例。 - CrandellWS
24个回答

114

data-dismiss使当前模态窗口强制关闭。

data-toggle打开一个新的模态窗口,其中包含 href 内容。

<a data-dismiss="modal" data-toggle="modal" href="#lost">Click</a>
或者
<a data-dismiss="modal" onclick="call the new div here">Click</a>

如果它有效,请告诉我们。


谢谢,它有效并避免使用“onclick”。但是动画仍然会在一秒钟内使滚动条翻倍。 - AlexioVay
@user2829128 这就是 data-dismiss 的作用。它关闭当前窗口并打开一个新窗口。你能在 bootplyjsfiddle 上发布你的代码吗? - jayeshkv
17
如果第二个模态框的高度很长,滚动功能将无法正常工作。 - Giraldi
同样的问题出现在Bootstrap v4中。当我点击第一个模态框上的按钮时,它会打开另一个模态框,第二个模态框会随着页面滚动。问题出在body的.modal-open类上。当我们点击后它被移除了,但没有再次添加回去。 - fdrv
16
.modal { overflow-y: auto } 可以解决 BS4 滚动问题。 - Riki137
显示剩余4条评论

100

我的解决方案并不关闭下层模态框,而是真正地堆叠在其上方。它正确地保留了滚动行为。在 Bootstrap 3 中进行了测试。为了使模态框按预期堆叠,您需要在 Html 标记中按从低到高的顺序对它们进行排序。

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

更新:当您堆叠多个模态框时,所有背景都出现在最下面的模态框下方。您可以通过添加以下 CSS 代码来解决这个问题:

.modal-backdrop { z-index: -1; }
.modal-backdrop {
    visibility: hidden !important;
}
.modal.in {
    background-color: rgba(0,0,0,0.5);
}

这将使最上面可见的模态框下方出现模态背景,以此方式使下面的较低模态框变灰。


为什么 HTML 中模态框的顺序很重要?我曾经遇到过这个问题。 - Csaba Toth
4
页面标记中靠后的项目具有自然更高的z-index,会堆叠在标记中较早出现的项目之上,除非您设置了显式的z-index。 - FirstVertex
8
JavaScript适用于Bootstrap 4,但CSS不适用。相反,我隐藏了背景并添加了以下代码: .modal:after { content: ""; display: block; background: rgba(0,0,0, .5); position: fixed; top: 0; bottom: 0; width: 100%; z-index: -1; } 该代码段的作用是在模态框后面添加了一个半透明黑色遮罩层。 - Jason G.
1
这是唯一一个对我在Bootstrap 4中有效的答案,结合了@JasonG.的提示。所有其他答案都会在第二级模态框关闭时禁用第一级模态框的滚动。 - Justin
1
Bootstrap 4 CSS: .modal-backdrop:nth-child(2n-1) { opacity : 0; } - alex

45

Bootstrap 5 (beta) - 2021年更新

模态框的默认z-index已更改为1060。因此,要覆盖模态框和背景,请使用...

.modal:nth-of-type(even) {
    z-index: 1062 !important;
}
.modal-backdrop.show:nth-of-type(even) {
    z-index: 1061 !important;
}

Bootstrap 5多重模态框


Bootstrap 4 - 2019年更新

我发现大部分答案似乎都包含了很多不必要的jQuery代码。从另一个模态框中打开模态框可以简单地使用Bootstrap提供的事件(如show.bs.modal)来完成。您可能还需要一些CSS来处理背景覆盖层。以下是三个“多重模态框”方案......

从另一个模态框中打开模态框(保持第一个模态框打开)

<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">
              <h4 class="modal-title">Modal title</h4>    
              <button type="button" class="close" data-dismiss="modal">×</button>
            </div><div class="container"></div>
            <div class="modal-body">
              ...
              <a data-toggle="modal" href="#myModal2" class="btn btn-primary">Open modal2</a>
            </div>
            <div class="modal-footer">
              <a href="#" data-dismiss="modal" class="btn">Close</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">
              <h4 class="modal-title">2nd Modal title</h4>
              <button type="button" class="close" data-dismiss="modal">×</button>
            </div><div class="container"></div>
            <div class="modal-body">
              ..
            </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>

在这种情况下可能存在的问题是第二个模态框的背景会隐藏第一个模态框。为了防止这种情况发生,可以将第二个模态框的data-backdrop="static",并添加一些CSS来修复背景的z-index...

/* modal backdrop fix */
.modal:nth-of-type(even) {
    z-index: 1052 !important;
}
.modal-backdrop.show:nth-of-type(even) {
    z-index: 1051 !important;
}

从另一个模态框中打开模态框(关闭第一个模态框)

这与上面的情况类似,但由于在打开第二个模态框时关闭了第一个模态框,因此不需要背景CSS修复。一个简单的函数可以处理第二个模态框的show.bs.modal事件以关闭第一个模态框。

https://codeply.com/go/NiFzSCukVl

$("#myModal2").on('show.bs.modal', function (e) {
    $("#myModal1").modal("hide");
});

https://codeply.com/go/ejaUJ4YANz


在另一个模态框内打开模态框

最后一个多个模态框的场景是在第一个模态框内打开第二个模态框。在这种情况下,第二个模态框的标记放置在第一个模态框内。不需要额外的CSS或jQuery。

<div class="modal" id="myModal1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">Modal title</h4>
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
            </div>
            <div class="container"></div>
            <div class="modal-body">
                ...
                <a data-toggle="modal" href="#myModal2" class="btn btn-primary">Launch modal 2</a>
            </div>
            <div class="modal-footer">
                <a href="#" data-dismiss="modal" class="btn">Close</a>
            </div>
        </div>
    </div>

    <div class="modal" id="myModal2">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title">2nd Modal title</h4>
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                </div>
                <div class="container"></div>
                <div class="modal-body">
                    ...
                </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>

https://codeply.com/go/iSbjqubiyn


在Bootstrap 4中它无法正常工作。当您关闭第二个模态框时,第一个模态框将不再滚动。 - Justin
1
我移除了 fade 类,即用 <div class="modal" 替换了 <div class="modal fade",这解决了我的问题。 - Muhammad Shahzad
1
它不适用于最新的Bootstrap版本,即v5.1.3。 - Sumit Parkash
1
只是测试与Bootstrap 3良好运作。 - Bang Nguyen
1
只是测试在Bootstrap 3下工作正常 - undefined
显示剩余5条评论

31

使用这个bootstrap-modal会将背景内容向右移动。 - Brian
@Brian - 请看这里:https://dev59.com/_FYO5IYBdhLWcg3wHd9o - lfkwtz

22

试一试

<!DOCTYPE html>
<html lang="en">
<head>
  <title></title>
  <meta charset="utf-8">
  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
  <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</head>
<body>

  <button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#test1">Open Modal 1 </button>



<div id="test1" class="modal fade" role="dialog" style="z-index: 1400;">
  <div class="modal-dialog">
    <!-- Modal content-->
    <div class="modal-content">
      
      <div class="modal-body">
       <button type="button" class="btn btn-info btn-lg" data-toggle="modal"      data-target="#test2">Open Modal 2</button>
       
      </div>      
    </div>
  </div>
</div>

<div id="test2" class="modal fade" role="dialog" style="z-index: 1600;">
  <div class="modal-dialog">
    <!-- Modal content-->
    <div class="modal-content">
      
      <div class="modal-body">
       
        content
       
      </div>      
    </div>
  </div>
</div>
  

</body>
</html>


2
对我来说失败了.. =( 模态框可以工作,但如果第一个模态框很长,会出现第一个模态框的滚动条,当您打开第二个模态框并关闭它时,第一个模态框的滚动将无法工作。 - Vincent Dapiton
非常感谢,这真的帮了我很大的忙 :) - Daniel Muñoz

19

您可以通过调用 hidden.bs.modal 事件实际上检测到旧模态窗口何时关闭:

    $('.yourButton').click(function(e){
        e.preventDefault();

        $('#yourFirstModal')
            .modal('hide')
            .on('hidden.bs.modal', function (e) {
                $('#yourSecondModal').modal('show');

                $(this).off('hidden.bs.modal'); // Remove the 'on' event binding
            });

    });

了解更多信息:http://getbootstrap.com/javascript/#modals-events


19

模态框中的模态框:

$('.modal-child').on('show.bs.modal', function () {
    var modalParent = $(this).attr('data-modal-parent');
    $(modalParent).css('opacity', 0);
});
 
$('.modal-child').on('hidden.bs.modal', function () {
    var modalParent = $(this).attr('data-modal-parent');
    $(modalParent).css('opacity', 1);
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<a href="#myModal" role="button" class="btn btn-primary" data-toggle="modal">Modals in Modal</a>


<div id="myModal" class="modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <!-- Modal content-->
        <div class="modal-content">
            <div class="modal-header">
             
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Modal Header</h4>
            </div>
            <div class="modal-body">
                <a href="#myModal1" role="button" class="btn btn-primary" data-toggle="modal">Launch other modal 1</a>
                <a href="#myModal2" role="button" class="btn btn-primary" data-toggle="modal">Launch other modal 2</a>
            </div>

        </div>
    </div>
</div>

<div id="myModal1" class="modal modal-child" data-backdrop-limit="1" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-modal-parent="#myModal">
    <div class="modal-dialog">
        <!-- Modal content-->
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Modal Header 1</h4>
            </div>
            <div class="modal-body">
                <p>Two modal body…1</p>
            </div>
            <div class="modal-footer">
                <button class="btn btn-default" data-dismiss="modal" data-dismiss="modal" aria-hidden="true">Cancel</button>
            </div>

        </div>
    </div>
</div>

<div id="myModal2" class="modal modal-child" data-backdrop-limit="1" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-modal-parent="#myModal">
    <div class="modal-dialog">
        <!-- Modal content-->
        <div class="modal-content">
            <div class="modal-header">
                
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Modal Header 2</h4>
            </div>
            <div class="modal-body">
                <p>Modal body…2</p>
            </div>
            <div class="modal-footer">
                <button class="btn btn-default" data-dismiss="modal" data-dismiss="modal" aria-hidden="true">Cancel</button>
            </div>

        </div>
    </div>
</div>


对我来说失败了.. =( 模态框可以工作,但如果第一个模态框很长,会出现第一个模态框的滚动条,当您打开第二个模态框并关闭它时,第一个模态框的滚动将无法工作。 - Vincent Dapiton
以上示例在第一个模态框的位置上生成了另一个模态框,而不是在其顶部(第一个模态框不再可见)。 - JackTheKnife
非常不错的效果。 - Jorge B.
您的解决方案如何在Semantic UI中使用? - vsam
我在我的项目中应用了这个解决方案,但是当我关闭模态框时,整个窗口变得模糊,无法点击任何东西。 - Azhar Uddin Sheikh

10

我正在处理一个有很多模态框相互调用的项目,有一些HTML工程师可能不知道每次为每个按钮初始化它。

最终得出了与@gmaggio类似的结论,但是在走了冗长的路之后才勉强接受。

编辑:现在支持通过JavaScript调用模态框。

编辑:从另一个模态框打开滚动模态框现在可行。

$(document).on('show.bs.modal', function (event) {
    if (!event.relatedTarget) {
        $('.modal').not(event.target).modal('hide');
    };
    if ($(event.relatedTarget).parents('.modal').length > 0) {
        $(event.relatedTarget).parents('.modal').modal('hide');
    };
});

$(document).on('shown.bs.modal', function (event) {
    if ($('body').hasClass('modal-open') == false) {
        $('body').addClass('modal-open');
    };
});

只需像往常一样放置模态调用按钮,如果它被识别为在一个模态内部,则会先关闭当前模态,然后再打开指定的模态,需要注意的是relatedTarget由Bootstrap提供。

我还添加了以下内容以使淡入淡出更加平滑:我相信还可以做更多。

.modal-backdrop.fade + .modal-backdrop.fade {
    transition: opacity 0.40s linear 0s;
}

不完全是你的问题,但 shown.bs.modal 钩子非常方便。在 BS v.3.3.5 中,body.modal-open 类的管理似乎存在缺陷,在关闭一个模态框并打开另一个模态框后,它会消失,因此背景会滚动而不是第二个模态框。您的钩子可以修复这种行为。 - Manuel Arwed Schmidt

9

对于Bootstrap 4,为了扩展@helloroy的答案,我使用了以下内容:

var modal_lv = 0 ;
$('body').on('shown.bs.modal', function(e) {
    if ( modal_lv > 0 )
    {
        $('.modal-backdrop:last').css('zIndex',1050+modal_lv) ;
        $(e.target).css('zIndex',1051+modal_lv) ;
    }
    modal_lv++ ;
}).on('hidden.bs.modal', function() {
    if ( modal_lv > 0 )
        modal_lv-- ;
});

上述方法的优点是,当只有一个模态时不会产生任何影响,仅在存在多个模态时才会发挥作用。其次,它将处理委托给body以确保未来生成的模态仍得到处理。 更新 采用js/css组合解决方案可改善外观-淡入淡出动画仍可在背景上工作。
var modal_lv = 0 ;
$('body').on('show.bs.modal', function(e) {
    if ( modal_lv > 0 )
        $(e.target).css('zIndex',1051+modal_lv) ;
    modal_lv++ ;
}).on('hidden.bs.modal', function() {
    if ( modal_lv > 0 )
        modal_lv-- ;
});

与以下CSS组合使用:-
.modal-backdrop ~ .modal-backdrop
{
    z-index : 1051 ;
}
.modal-backdrop ~ .modal-backdrop ~ .modal-backdrop
{
    z-index : 1052 ;
}
.modal-backdrop ~ .modal-backdrop ~ .modal-backdrop ~ .modal-backdrop
{
    z-index : 1053 ;
}

这将处理嵌套模态框,最多可以嵌套4层,这已经超出我的需求范围。

在Bootstrap 4中它无法正常工作。当您关闭第二个模态框时,第一个模态框将不再滚动。 - Justin
太棒了!我正在使用Bootsfaces 1.5.0版本,只需要使用CSS,并将z-index添加到“b:modal”元素中即可。 - JonathanDavidArndt

8

Twitter文档指出需要自定义代码...

这可以不需额外的JavaScript工具实现, 然而,强烈建议使用自定义CSS...

<link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<!-- Button trigger modal -->
    <button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#modalOneModal">
      Launch demo modal
    </button> 
            <!-- Modal -->
            <div class="modal fade bg-info" id="modalOneModal" tabindex="-1" role="dialog" aria-labelledby="modalOneLabel" aria-hidden="true">
    
              <div class="modal-dialog">
          
                <div class="modal-content  bg-info">
                  <div class="modal-header btn-info">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                    <h4 class="modal-title" id="modalOneLabel">modalOne</h4>
                  </div>
                  <div id="thismodalOne" class="modal-body bg-info">
                
                
              <!-- Button trigger modal -->
    <button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#twoModalsExample">
      Launch demo modal
    </button>
             
                    <div class="modal fade bg-info" id="twoModalsExample" style="overflow:auto" tabindex="-1" role="dialog" aria-hidden="true">
                <h3>EXAMPLE</h3>
            </div>
                  </div>
                  <div class="modal-footer btn-info" id="woModalFoot">
                    <button type="button" class="btn btn-info" data-dismiss="modal">Close</button>
                  </div>
                </div>
              </div>
            </div>
    <!-- End Form Modals -->


1
这里是另一个示例,第二个模态框已正确格式化 http://www.bootply.com/qRsvPSrcO5 - Carol Skelly
1
@Skelly在CSS中更改z-index是个好主意... z-index: 1080 !important; - CrandellWS
4
如果你打开第二个弹出窗口并在外面点击,它将会出现故障。(Chrome浏览器,最新版本) - Martin Braun
也许我错了,但我相信文档说不要在模态框中放置另一个模态框,所以这并不令人惊讶。 - CrandellWS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接