我尝试在另一个模态中使用模态。但是,我遇到了一个类似于too much recursion
Firefox 的错误。
我使用了最新的 jQuery 和 Twitter 引导程序,但仍然有这个问题。
这是显示错误的plunker
您可以在控制台中找到错误Uncaught RangeError: Maximum call stack size exceeded
或too much recursion
有谁知道如何修理它?谢谢
我尝试在另一个模态中使用模态。但是,我遇到了一个类似于too much recursion
Firefox 的错误。
我使用了最新的 jQuery 和 Twitter 引导程序,但仍然有这个问题。
这是显示错误的plunker
您可以在控制台中找到错误Uncaught RangeError: Maximum call stack size exceeded
或too much recursion
有谁知道如何修理它?谢谢
您可以应用 maxisam 答案的第一个解决方案,而无需修改引导文件(如果您不能或不想)。
只需在包含引导文件后的某处写下这一行。
$.fn.modal.Constructor.prototype.enforceFocus = function () {};
注意:这仅在 Bootstrap 2 中进行了测试,而不是在 Bootstrap 3 中进行了测试。
好的,这似乎是一个已经发现的问题。
(显然我应该使用关键字“未捕获的 RangeError:超出最大调用堆栈大小”而不是“递归过多”:()
以下是解决方案。
1.修改modal.js
在这篇文章中,https://github.com/twbs/bootstrap/pull/5022
@onassar 提出解决方案
跟进:对于使用 bootstrap-modal v2.2.0 的任何人,在 enforceFocus 方法中,注释掉 that.$element.focus() 似乎可以解决问题。
这样做的结果是模态不被关注(pfft,我自己可以做到这一点:P),因此,多个模态不会相互挑战焦点(导致无限循环,并且范围错误/递归循环)。
希望有帮助:)
我试过了,它有效。(笨蛋)
看起来它工作得很好。
3.等待官方解决。
在他们的路线图中,他们确实想在某个时候重写这个模态插件。
不幸的是,SmartLove 的回答不够;如果您要使用 no-op $.fn.modal.Constructor.prototype.enforceFocus
,则应在模式关闭时将其重置;以下直接来自我们的代码,我对投入生产没有疑虑:
// Since confModal is essentially a nested modal it's enforceFocus method
// must be no-op'd or the following error results
// "Uncaught RangeError: Maximum call stack size exceeded"
// But then when the nested modal is hidden we reset modal.enforceFocus
var enforceModalFocusFn = $.fn.modal.Constructor.prototype.enforceFocus;
$.fn.modal.Constructor.prototype.enforceFocus = function() {};
$confModal.on('hidden', function() {
$.fn.modal.Constructor.prototype.enforceFocus = enforceModalFocusFn;
});
$confModal.modal({ backdrop : false });
4. 或者您可以在显示新模态时执行以下操作:
当您关闭新模态时,显示以前隐藏的模态
var showModal = function ($dialog) {
var $currentModals = $('.modal.in');
if ($currentModals.length > 0) { // if we have active modals
$currentModals.one('hidden', function () {
// when they've finished hiding
$dialog.modal('show');
$dialog.one('hidden', function () {
// when we close the dialog
$currentModals.modal('show');
});
}).modal('hide');
} else { // otherwise just simply show the modal
$dialog.modal('show');
}
};
注意:我$.one
以前只应用一次监听器而不关心bind
/ unbind
( on
/ off
)
对于 Bootstrap 4,替换 :
$.fn.modal.Constructor.prototype.**enforceFocus**
By
$.fn.modal.Constructor.prototype.**_enforceFocus**
试试下面的css。它对我有用。
span.select2-container {
z-index:10050;
}
@Dexygen 答案的 Bootstrap 5 版本:
const enforceModalFocusFn = bootstrap.Modal.prototype._enforceFocus ;
const onMyModalHidden = function(){
bootstrap.Modal.prototype._enforceFocus = enforceModalFocusFn;
}
//let modalElem = ...;
modalElem.addEventListener('hidden.bs.modal', onMyModalHidden);
bootstrap.Modal.prototype._enforceFocus = function () {};
重要提示:您必须在显示模式之前覆盖该功能。这意味着即在“show.bs.modal”上。如果您稍后初始化覆盖,即在“shown.bs.modal”上它不会工作,因为原始函数已经通过。
同样适用于 offcanvas(这是我需要的),只需将 .Modal 更改为 .Offcanvas 并将 _enforceFocus 更改为 _enforceFocusOnElement
我使用堆栈解决了这个问题。
var openmodals = [];
$(function(){
var ts = new Date().getTime();
$("div.modal").each(function( d ) {
ts++;
$( this ).data( "uid", ts );
});
// after closing > 1 level modals we want to reopen the previous level modal
$('div.modal').on('show', function ( d ) {
openmodals.push({ 'id' : $( this ).data( "uid" ), 'el' : this });
if( openmodals.length > 1 ){
$( openmodals[ openmodals.length - 2 ].el ).modal('hide');
}
});
$('div.modal').on('hide', function ( d ) {
if( openmodals.length > 1 ){
if( openmodals[ openmodals.length - 1 ].id == $( this ).data( "uid" ) ){
openmodals.pop(); // pop current modal
$( openmodals.pop().el ).modal('show'); // pop previous modal and show, will be pushed on show
}
} else if( openmodals.length > 0 ){
openmodals.pop(); // last modal closing, empty the stack
}
});
});
可以省略:tabindex="-1"
,在modal的顶部,可以通过方式打开modal:$('#modal').show();
并关闭:$('#modal').hide();
注意:需要JQuery才能工作。