別のモーダル内にモーダルを持たせようとしています。too much recursionしかし、 firefoxのようなエラーが出ました。
最新の jQuery と Twitter ブートストラップを使用しましたが、まだこの問題があります。
これがエラーを示すプランカーです
コンソールUncaught RangeError: Maximum call stack size exceededまたはtoo much recursion
誰もそれを修正する方法を知っていますか? ありがとう
別のモーダル内にモーダルを持たせようとしています。too much recursionしかし、 firefoxのようなエラーが出ました。
最新の jQuery と Twitter ブートストラップを使用しましたが、まだこの問題があります。
これがエラーを示すプランカーです
コンソールUncaught RangeError: Maximum call stack size exceededまたはtoo much recursion
誰もそれを修正する方法を知っていますか? ありがとう
わかりました、それは発見された問題のようです。
(明らかに、「再帰が多すぎる」の代わりに「Uncaught RangeError: 最大呼び出しスタック サイズを超えました」というキーワードを使用する必要があります:()
ここに解決策があります。
1. modal.js を修正する
この投稿では、https://github.com/twbs/bootstrap/pull/5022
@onassarが解決策を提示
フォローアップ: bootstrap-modal v2.2.0 を使用している場合は、enforceFocus メソッドで that.$element.focus() をコメントアウトすると問題が解決するようです。
この結果、モーダルはフォーカスされず (pfft、私は自分でそれを行うことができます:P)、したがって、複数のモーダルはフォーカスを求めて互いに挑戦しません (その結果、無限ループが発生し、 rangerror/再帰ループ)。
それが役立つことを願っています:)
私は試してみましたが、うまくいきます。(プランカー)
それはかなりうまくいくようです。
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');
}
};
注: 私はリスナーを 1 回だけ適用し、 / ( / )$.oneを気にしませんでした。bindunbindonoff
@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
}
});
});