61

別のモーダル内にモーダルを持たせようとしています。too much recursionしかし、 firefoxのようなエラーが出ました。

最新の jQuery と Twitter ブートストラップを使用しましたが、まだこの問題があります。

これがエラーを示すプランカーです

コンソールUncaught RangeError: Maximum call stack size exceededまたはtoo much recursion

誰もそれを修正する方法を知っていますか? ありがとう

4

9 に答える 9

34

わかりました、それは発見された問題のようです。

(明らかに、「再帰が多すぎる」の代わりに「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/再帰ループ)。

それが役立つことを願っています:)

私は試してみましたが、うまくいきます。(プランカー)

2.別のプラグイン を使用してこのデモに対処する

それはかなりうまくいくようです。

3. 正式な解決を待ちます。

彼らのロードマップでは、ある時点でこのモーダル プラグインを書き直したいと考えています。

于 2012-11-30T16:52:54.403 に答える
32

残念ながら、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 });
于 2013-10-04T20:28:50.743 に答える
7

4. または、新しいモーダルを表示するときに次のようにすることもできます。

  1. 現在アクティブなモーダルを非表示にする
  2. 新しいモーダルを表示
  3. 新しいモーダルを閉じると、以前に非表示だったモーダルが表示されます

    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

于 2013-03-24T11:29:25.930 に答える
2

@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 に変更するだけです。

于 2021-06-19T19:16:23.033 に答える
1

スタックを使用してこれを解決しました。

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
    } 
  });
});
于 2013-06-26T20:32:11.257 に答える