我有一个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">×</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>
答案 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);
$(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">×</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;
注意:我还没有检查过源代码,或者对这些模态进行了实验,足以知道完成这项工作所需的最小延迟时间。但是,我不介意延迟一秒钟,因为它几乎不会引人注意。
作为you suggest,等待Bootstrap的hidden.bs.modal
事件在这种情况下更好。如v3 Docs here:
当模态完成对用户的隐藏时将触发此事件(将等待CSS转换完成)。
将promise.resolved
移动到hidden.bs.modal
的事件处理程序也可以解决问题。
为此,我添加了一个变量modalResult
,用于跟踪用户的选择,并相应地触发deferred.resolve
或deferred.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();
}
&#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">×</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;