Javascript 为什么使用 twitter bootstrap 的多模态错误太多递归?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13649459/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 12:34:51  来源:igfitidea点击:

Why does multiple modal using twitter bootstrap got error too much recursion?

javascriptjquerytwitter-bootstrap

提问by maxisam

I try to have a modal inside another modal. However, I got an error like too much recursionin firefox.

我尝试在另一个模态内有一个模态。但是,我遇到了类似too much recursionFirefox的错误。

I used the latest jQuery and Twitter bootstrap but still have this problem.

我使用了最新的 jQuery 和 Twitter 引导程序,但仍然有这个问题。

Here is the plunkerthat shows the error

这是显示错误的plunker

You can find errors in console Uncaught RangeError: Maximum call stack size exceededor too much recursion

您可以在控制台Uncaught RangeError: Maximum call stack size exceededtoo much recursion

Does anyone know how to fix it? Thanks

有谁知道如何修理它?谢谢

采纳答案by maxisam

Ok, it seems like an issue that has been discovered.

好吧,看来是发现了一个问题。

(apparently I should use key word "Uncaught RangeError: Maximum call stack size exceeded" instead of "too much recursion" :( )

(显然我应该使用关键字“未捕获的范围错误:超出最大调用堆栈大小”而不是“递归过多”:()

Here are the solutions.

以下是解决方案。

1. modify the modal.js

1.修改modal.js

in this post, https://github.com/twbs/bootstrap/pull/5022

在这篇文章中,https://github.com/twbs/bootstrap/pull/5022

@onassar bring up a solution

@onassar 提出解决方案

Follow up: for anyone working with bootstrap-modal v2.2.0, in the enforceFocus method, commenting out that.$element.focus() seems to fix the issue.

The result of this is the modal's don't get focused upon (pfft, I can do that myself :P), and thus, the multiple modals don't challenge one-another for focus (which resulted in an infinite loop, and a rangerror/recursive loop).

Hope that helps :)

跟进:对于使用 bootstrap-modal v2.2.0 的任何人,在 enforceFocus 方法中,注释掉 that.$element.focus() 似乎可以解决这个问题。

这样做的结果是模态不会被关注(pfft,我自己可以做到:P),因此,多个模态不会相互挑战焦点(这导致了无限循环,并且范围错误/递归循环)。

希望有帮助:)

I tried and it works. (plunker)

我试过了,它有效。(笨蛋)

2. Use another pluginto address thisDemo

2.使用另一个插件来解决这个Demo

It seems like it works pretty well.

看起来它工作得很好。

3. Wait for official solution.

3.等待官方解决。

In their roadmap, they do want to rewrite this modal plugin at some point.

在他们的路线图中,他们确实想在某个时候重写这个模态插件。

回答by Tony - Currentuser.io

You can apply the first solution of maxisam answer, without modifying bootstrap files (if you can not, or don't want to).

您可以应用 maxisam 答案的第一个解决方案,而无需修改引导程序文件(如果您不能或不想)。

Just write this line somewhere after bootstrap files have been included.

只需在包含引导程序文件后的某处写下这一行。

$.fn.modal.Constructor.prototype.enforceFocus = function () {};

Note:This has been tested with Bootstrap 2 only, not with Bootstrap 3.

注意:这仅在 Bootstrap 2 上测试过,没有在 Bootstrap 3 上测试过。

回答by Dexygen

SmartLove's answer unfortunately falls short; if you're going to no-op $.fn.modal.Constructor.prototype.enforceFocus, you should reset it when your modal closes; the following is directly from our code, about which I have no qualmsputting into production:

不幸的是,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 });

回答by Matyas

4. Or you could do the following when showing a new modal:

4. 或者您可以在显示新模态时执行以下操作:

  1. Hide any modal that is currently active
  2. Show the new modal
  3. When you close the new modal, show previously hidden modal(s)

    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. 隐藏当前处于活动状态的任何模态
  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');
        }
    };
    

Note: I use $.oneto only have the listener applied once and not to care about bind/unbind(on/off)

注意:我$.one过去只应用一次监听器而不关心bind/ unbind( on/ off)

回答by nidhin

Try the following css. It worked for me.

试试下面的css。它对我有用。

span.select2-container {
    z-index:10050;
}

回答by bbastou

For Bootstrap 4, replace : $.fn.modal.Constructor.prototype.**enforceFocus**By $.fn.modal.Constructor.prototype.**_enforceFocus**

对于 Bootstrap 4,替换 : $.fn.modal.Constructor.prototype.**enforceFocus**By $.fn.modal.Constructor.prototype.**_enforceFocus**

回答by Ryan

I solved this using a stack.

我使用堆栈解决了这个问题。

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
    } 
  });
});