简体   繁体   English

依次显示Bootstrap模态对话框

[英]Showing Bootstrap modal dialogs in sequence

I have a Bootstrap modal dialog, which when Yes is selected returns a resolved promise. 我有一个Bootstrap模态对话框,当选择“是”时,它将返回一个已解决的Promise。 Upon the promise being resolved, the modal should be displayed again. 兑现承诺后,应再次显示模式。 The line to display the modal is hit, but the modal does not display. 点击了显示模态的行,但是模态没有显示。 What am I doing wrong? 我究竟做错了什么?

 $(function() { showModalDialog('Confirm1', "Select Yes or No", 'Yes', 'No') .done(function() { alert('You selected Yes once!'); showModalDialog('Confirm2', "Select Yes or No", 'Yes', 'No') .done(function() { alert('You selected Yes twice!'); }); }); }); function showModalDialog(title, message, button1Caption, button2Caption) { var deferred = $.Deferred(); $('#modalTitle').html(title); $('#modalMessage').html(message); $('#modalButton1').html(button1Caption); $('#modalButton2').html(button2Caption); $('#modalButton1').one('click', function() { deferred.resolve(); }); $('#modalButton2').one('click', function() { deferred.reject(); }); $('#modalDialog').one('hidden.bs.modal', function() { //remove the handler for the button in case it was never invoked, otherwise it will //still be there the next time the dialog is shown $('#modalButton1').off('click'); deferred.reject(); }) $('#modalDialog').modal(); return deferred.promise(); } 
 <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <div class="modal fade" id="modalDialog" tabindex="-1" role="dialog" aria-labelledby="modalTitle" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <!--<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>--> <h4 class="modal-title" id="modalTitle"></h4> </div> <div class="modal-body" id="modalMessage"></div> <div class="modal-footer"> <button type="button" id="modalButton1" class="btn btn-default" data-dismiss="modal"></button> <button type="button" id="modalButton2" class="btn btn-default" data-dismiss="modal"></button> </div> </div> </div> </div> 

Blame the animations! 怪动画! :) :)

The animation of the hiding modal takes some finite time to complete. 隐藏模态的动画需要一定的时间才能完成。 If you try to "show" the modal again during this time, it will not work. 如果您在此期间尝试再次“显示”模态,它将无法正常工作。 A simple workaround is to delay the "show" action slightly. 一个简单的解决方法是稍微延迟“显示”操作。

For example, delaying it by one second will work just fine: 例如,将其延迟一秒就可以了:

setTimeout(function() {
    showModalDialog('Confirm2', "Select Yes or No", 'Yes', 'No')
      .done(function() {
        alert('You selected Yes twice!');
      });
}, 1000);

 $(function() { showModalDialog('Confirm1', "Select Yes or No", 'Yes', 'No') .done(function() { alert('You selected Yes once!'); setTimeout(function() { showModalDialog('Confirm2', "Select Yes or No", 'Yes', 'No') .done(function() { alert('You selected Yes twice!'); }); }, 1000); }); }); function showModalDialog(title, message, button1Caption, button2Caption) { var deferred = $.Deferred(); $('#modalTitle').html(title); $('#modalMessage').html(message); $('#modalButton1').html(button1Caption); $('#modalButton2').html(button2Caption); $('#modalButton1').one('click', function() { deferred.resolve(); }); $('#modalButton2').one('click', function() { deferred.reject(); }); $('#modalDialog').one('hidden.bs.modal', function() { //remove the handler for the button in case it was never invoked, otherwise it will //still be there the next time the dialog is shown $('#modalButton1').off('click'); deferred.reject(); }) $('#modalDialog').modal(); return deferred.promise(); } 
 <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <div class="modal fade" id="modalDialog" tabindex="-1" role="dialog" aria-labelledby="modalTitle" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <!--<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>--> <h4 class="modal-title" id="modalTitle"></h4> </div> <div class="modal-body" id="modalMessage"></div> <div class="modal-footer"> <button type="button" id="modalButton1" class="btn btn-default" data-dismiss="modal"></button> <button type="button" id="modalButton2" class="btn btn-default" data-dismiss="modal"></button> </div> </div> </div> </div> 

Note: I haven't checked the source code or experimented with these modals enough to know the minimum amount of delay required to make this work. 注意:我还没有检查源代码或对这些模式进行足够的试验,以了解完成此工作所需的最小延迟量。 But I don't mind a delay of one second anyway as it is barely noticeable. 但是我也不介意延迟一秒钟,因为这几乎没有引起注意。

Update 更新资料

As you suggest , waiting for Bootstrap's hidden.bs.modal event is a better in this case. 您所建议 ,在这种情况下,等待Bootstrap的hidden.bs.modal事件更好。 As described in the v3 Docs here : 如此处的v3文档所述:

This event is fired when the modal has finished being hidden from the user (will wait for CSS transitions to complete). 当模态完成向用户隐藏时将触发此事件(将等待CSS转换完成)​​。

So moving the promise.resolved to the event handler for hidden.bs.modal would also do the trick. 让人感动的promise.resolved到事件处理程序hidden.bs.modal也将这样的伎俩。

To do that, I've added a variable modalResult which keeps track of user's choice, and triggers deferred.resolve or deferred.reject accordingly. 为此,我添加了一个变量modalResult ,该变量跟踪用户的选择,并相应地触发deferred.resolvedeferred.reject

 $(function() { showModalDialog('Confirm1', "Select Yes or No", 'Yes', 'No') .done(function() { alert('You selected Yes once!'); showModalDialog('Confirm2', "Select Yes or No", 'Yes', 'No') .done(function() { alert('You selected Yes twice!'); }); }); }); function showModalDialog(title, message, button1Caption, button2Caption) { var modalResult = false; var deferred = $.Deferred(); $('#modalTitle').html(title); $('#modalMessage').html(message); $('#modalButton1').html(button1Caption); $('#modalButton2').html(button2Caption); $('#modalButton1').one('click', function() { // Wait for the modal to get hidden. // deferred.resolve(); modalResult = true; }); $('#modalButton2').one('click', function() { // Wait for the modal to get hidden. // deferred.reject(); modalResult = false; }); $('#modalDialog').one('hidden.bs.modal', function() { //remove the handler for the button in case it was never invoked, otherwise it will //still be there the next time the dialog is shown $('#modalButton1').off('click'); if(modalResult) { deferred.resolve(); } else { deferred.reject(); } }) $('#modalDialog').modal(); return deferred.promise(); } 
 <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <div class="modal fade" id="modalDialog" tabindex="-1" role="dialog" aria-labelledby="modalTitle" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <!--<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>--> <h4 class="modal-title" id="modalTitle"></h4> </div> <div class="modal-body" id="modalMessage"></div> <div class="modal-footer"> <button type="button" id="modalButton1" class="btn btn-default" data-dismiss="modal"></button> <button type="button" id="modalButton2" class="btn btn-default" data-dismiss="modal"></button> </div> </div> </div> </div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM