按顺序显示Bootstrap模态对话框

时间:2017-10-21 04:52:46

标签: javascript jquery twitter-bootstrap

我有一个Bootstrap模式对话框,当选择Yes时会返回已解决的promise。在承诺得到解决后,应再次显示模态。显示模态的线被击中,但模态不显示。我做错了什么?

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

1 个答案:

答案 0 :(得分:2)

归咎于动画! :)

隐藏模态的动画需要一些有限的时间才能完成。如果你试图&#34;显示&#34;在这段时间内再次使用模态,它将无法工作。一个简单的解决方法是延迟&#34; show&#34;行动稍微。

例如,将它延迟一秒就可以正常工作:

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

&#13;
&#13;
$(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();
}
&#13;
<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>
&#13;
&#13;
&#13;

注意:我还没有检查过源代码,或者对这些模态进行了实验,足以知道完成这项工作所需的最小延迟时间。但是,我不介意延迟一秒钟,因为它几乎不会引人注意。

更新

作为you suggest,等待Bootstrap的hidden.bs.modal事件在这种情况下更好。如v3 Docs here

中所述
  

当模态完成对用户的隐藏时将触发此事件(将等待CSS转换完成)​​。

promise.resolved移动到hidden.bs.modal的事件处理程序也可以解决问题。

为此,我添加了一个变量modalResult,用于跟踪用户的选择,并相应地触发deferred.resolvedeferred.reject

&#13;
&#13;
$(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();
}
&#13;
<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>
&#13;
&#13;
&#13;