【问题标题】:Bootstrap Modal Backdrop Remaining剩余的 Bootstrap 模态背景
【发布时间】:2014-03-30 03:39:18
【问题描述】:

我在执行 AJAX 调用时显示一个用于加载的 Bootstrap 模式窗口。当加载模式应该显示时,我广播一个“progress.init”事件,当我希望模式隐藏时广播一个“progress.finish”。在某些情况下,模态显示后会很快隐藏,导致模态背景保留在屏幕上。隐藏元素的后续调用不会删除背景。我也不能简单地删除所有背景,因为其他模式窗口可能会显示在加载窗口上。我已经整理了一个jsfiddle 来展示简单调用模态函数(而不是触发事件)的问题。

var loadingModal = $("#loadingModal");

$("#btnShow").click(function () {
   loadingModal.modal("show");
    //hide after 3 seconds
    setTimeout(function () {
        loadingModal.modal("hide");
    }, 3000);
});

$("#btnProblem").click(function () {
   //simulate a loading screen finishing fast, followed by another loading screen
    loadingModal.modal("show");
    loadingModal.modal("hide");
    loadingModal.modal("show");

    //Again simulate 3 seconds
    setTimeout(function () {
        loadingModal.modal("hide");
    }, 3000);
});

还有 HTML:

<div id="loadingModal" class="modal fade">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-body">
        <p>Loading...</p>
      </div>
    </div>
  </div>
</div>
<button id="btnShow">Show Loading</button>
<button id="btnProblem">Cause show/hide problem</button>

理想情况下,我希望在调用 modal("hide") 之前无需等待指定时间即可解决此问题。换句话说,我想尽量避免这样的事情:

elem.on("progress.finish", function () {
    window.setTimeout(loadingModal.modal("hide");
}, 750);

我还尝试从 bootstrap 订阅 hidden.bs.modal 和 shown.bs.modal 事件以尝试显示/隐藏元素(如果需要),但可能会出现此错误...任何想法允许此模式显示/隐藏?

【问题讨论】:

标签: javascript twitter-bootstrap-3


【解决方案1】:

如果在模态隐藏之后,褪色的背景仍然存在,并且不允许您单击任何可以使用下面的代码强制删除它们的位置。

首先隐藏(全部)您的模态 div 元素。

$('.modal').modal('hide');

其次从正文中删除“modal-open”类和页面末尾的“.modal-backdrop”。

$('body').removeClass('modal-open');
$('.modal-backdrop').remove();

【讨论】:

  • 非常感谢...其他人给出的答案在我看来并不完整。它只是隐藏起来,不允许您在后屏幕上进行其他操作。你的代码解决了我的问题。再次非常感谢 Gampesh。
  • 只是与我分享发生的事情,直到昨天我才遇到这个问题。我所有的模态都是由一些自动 PHP 代码和 JS 生成的。当我将模态 ID 设置为“模态”时,问题就开始了。只需更改它并再次停止问题。
  • 补充说,这解决了我使用由 asp.net 模式中的按钮触发的回发的问题。上面的 javascript 在回发完成后执行时修复了覆盖问题。
  • 谢谢,这只是对我有用的东西。实际上我需要的唯一一行是 $('.modal-backdrop').remove();
  • 不需要更多的东西:$('body').css('paddingRight', 0); 否则,由于手动删除模态,17px 的填充被添加到正文中。
【解决方案2】:

以防万一其他人遇到类似的问题:我发现即使在模态隐藏之后,将类“淡化”从模态中移除也会防止背景粘在屏幕上。这似乎是用于模式的 bootstrap.js 中的一个错误。

另一个(同时保持淡入淡出效果)是用您自己的自定义 javascript 替换对 jQueryElement.modal 的调用,该 javascript 添加“in”类,设置 display: 块,并在显示时添加背景,然后执行想要隐藏模态框时的相反操作。

对于我的项目来说,只需移除淡入淡出就足够了。

【讨论】:

  • 为我工作!谢谢!
  • 这个答案是 $(".modal-backdrop").remove();为我工作
  • 就我而言,没有淡入淡出类。但是这个$('.modal').modal('hide'); 而不是$('.modal').hide(); 对我有用。取自 Gampesh 的答案。
【解决方案3】:

以防万一其他人遇到类似问题:我保留了淡入淡出,但只是在保存按钮中添加了data-dismiss="modal"。对我有用。

【讨论】:

  • 删除“fade”类会导致 UI 不以默认方式运行。模态只是出现而不是从顶部慢慢淡入。但是,添加 data-dismiss="modal" 确实为我解决了这个问题。我认为这是一种比公认答案更好的方法,因为它利用了 Bootstrap 预定义的数据属性,而不是更改默认 UI 和行为..
  • 这应该是最好的答案
  • 问题是,如果需要验证表单,data-dismiss 会关闭模态
  • 为此苦苦挣扎,我实际上是通过自定义模态 ID 来代替文本作为模态。感谢问答。
【解决方案4】:

问题在于引导程序会异步删除背景。因此,当您快速调用hideshow 时,不会移除背景。

解决方案(正如您所提到的)是使用 'hidden.bs.modal' 事件等待模态完全隐藏。使用 jQuery one 只执行一次回调。我已经分叉了你的jsfiddle 来展示它是如何工作的。

// wait for the backdrop to be removed nicely.
loadingModal.one('hidden.bs.modal', function()
{
    loadingModal.modal("show");

    //Again simulate 3 seconds
    setTimeout(function () {
        loadingModal.modal("hide");
    }, 3000);
});
// hide for the first time, after binding to the hidden event.
loadingModal.modal("hide");

在 Bootstrap 中浏览代码:

This is what makes hiding the modal asynchronous:

$.support.transition && this.$element.hasClass('fade') ?
    this.$element
        .one('bsTransitionEnd', $.proxy(this.hideModal, this))
        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
    this.hideModal()

这会检查是否支持转换,并且fade 类是否包含在模态中。当两者都是true 时,它会等待淡入淡出效果完成,然后再隐藏模态。在removing the backdrop之前等待happens again

这就是为什么删除淡入淡出类会使隐藏模式同步(不再等待 CSS 淡入淡出效果完成)以及 reznic 的解决方案有效的原因。

This check 确定是否添加或删除背景。 isShown = true is performed synchronously。当您快速调用 hideshow 时,isShown 将变为 true,并且检查会添加背景,而不是删除前一个,从而产生您遇到的问题。

【讨论】:

  • 最全的答案!
  • 这对我有帮助。我在ajaxStart() 上显示modal 并将其隐藏在ajaxComplete() 上,因此当一次有多个ajax 调用时,会有多个背景实例。删除 fade 类就可以了。谢谢!
  • 有没有办法让'fade'同步而不是异步?
【解决方案5】:

如果您不需要这样的背景,解决方法是完全隐藏背景: 数据背景=""

<div class="modal fade preview-modal" data-backdrop="" id="preview-modal"  role="dialog" aria-labelledby="preview-modal" aria-hidden="true">

【讨论】:

  • 你刚刚救了我一个沮丧的夜晚。谢谢!
  • 唯一对我有用的解决方案是preview-modal,谢谢。
【解决方案6】:

这对我有用 -

hidden.bs.modal 事件被触发时,jQuery.remove() 函数可以删除具有.modal-backdrop 类的元素。所以每次模态框关闭时,modal-backdrop都会被移除

//setting callback function for 'hidden.bs.modal' event
$('#modal').on('hidden.bs.modal', function(){
  //remove the backdrop
  $('.modal-backdrop').remove();
})

祝你好运。

【讨论】:

    【解决方案7】:

    最好和最简单的方法是使用data-dismiss 属性。基本上,data-dismiss 属性将关闭模式,您将看不到剩余的背景。

    如何使用 data-dismiss 属性

    您需要做的就是在要关闭模式的地方添加以下内容:

    data-dismiss="modal" 
    

    例如,我有一个按钮,当有人单击该按钮时,它将关闭模式。

    <button class="btn btn-info float-right" onclick="foo()" data-dismiss="modal">Save changes</button>
    

    您还可以在onClick 上处理 JavaScript 函数,它将关闭模态并运行 JavaScript 函数。

    这是使用data-dismiss 属性的最佳方法。

    【讨论】:

      【解决方案8】:

      添加:
          $(".modal-backdrop").hide();
      到控制器中的 ng-click 功能,以防止淡入背景停留。

      【讨论】:

        【解决方案9】:

        只需从模态中删除类 'fade'

        【讨论】:

        • 虽然这可能会解决问题,但您的回答将受益于一些解释。为什么这能解决问题?
        • 我知道这将是一个很好的解释,但删除类“淡入淡出”确实解决了问题。谢谢你。
        【解决方案10】:

        检查元素后,在我点击浏览器后退按钮后,带有modal-backdrop 类的div 仍然存在,所以我只需将其删除:

        $(window).on('popstate', function() {
            $(".modal-backdrop").remove();
        });
        

        【讨论】:

        • 它不允许我在我的页面上滚动
        • 这对我有用,谢谢.....
        【解决方案11】:

        对于 Bootstrap 4,这应该适合你

         $('.modal').remove();
         $('.modal-backdrop').remove();
        

        【讨论】:

          【解决方案12】:

          在模态中使用关闭按钮,此方法工作正常:

          <input type="button" class="btn btn-default" data-dismiss="modal" value="Cancel" id="close_model">
          

          成功后使用:

          $('#model_form').trigger("reset"); // for cleaning a modal form
          $('#close_model').click(); // for closing a modal with backdrop
          

          【讨论】:

            【解决方案13】:

            另一种可能的情况(我的) - 您正在将模态 html 动态添加到 DOM,它包含更多的 1 个根节点。这里的问题是评论节点也很重要,所以,如果你从引导站点复制模板 - 你就有了。

            【讨论】:

            • 非常感谢!这正是我的情况!
            【解决方案14】:

            执行动作后触发关闭按钮。

            例子

            $('.close').click();

            【讨论】:

              【解决方案15】:

              对于仍在为这个问题苦苦挣扎的人,我找到了解决方法

              首先为您的关闭按钮添加一个 id(如果您不需要或有一个,您可以使其不可见)

              <button id="buttonDismiss" type="button" class="close" data-dismiss="modal" aria-label="Close">
              

              并在您的 Ajax 调用中使用 Javascript 而不是 Jquery 触发点击(丢失对您的 Modal 的引用)

              document.getElementById("buttonDismiss").click();
              

              【讨论】:

              • 这对我来说是完美的解决方案。我不想加载 jQuery 只是为了解决这个问题!而所有其他答案都没有 100% 起作用。通过纯 Javascript 单击关闭按钮是一个很棒的完整解决方案,谢谢!
              【解决方案16】:

              试试这个

              $('.modal').on('hide.bs.modal', function () {
                  if ($(this).is(':visible')) {
                     console.log("show modal")
                     $('.modal-backdrop').show();
                  }else{
                      console.log("hidden modal");
                      $('.modal-backdrop').remove();
                  }
              })
              

              【讨论】:

                【解决方案17】:

                为了绕过在 boostrap.js modal.hide() 之后挥之不去的背景,我给模式中的关闭按钮一个 id,并以编程方式发送一个点击事件。

                <div class="modal-header">
                    <h5 class="modal-title">{{title}}</h5>
                    <button 
                        type="button" 
                        class="btn-close" 
                        data-bs-dismiss="modal" 
                        aria-label="Close"
                        :id="`${id}-btn-close`" ></button> 
                </div>
                
                
                ...
                
                hideModal (modalElementId = 'modal') {
                    // Workaround issue with modal.hide() leaving the overlay behind.
                    var modalCloseButton = document.getElementById(`${modalElementId}-btn-close`);
                    if (modalCloseButton !== null) {
                        modalCloseButton.click();
                    }
                }
                

                【讨论】:

                • 将点击事件发送到关闭按钮是一个令人难以置信的 hacky 解决方案,比线程中的其他答案更糟糕。
                【解决方案18】:

                小心添加 {data-dismiss="modal"} 如第二个答案所述。当使用控制器范围定义的函数使用 Angulars ng-commit 时,将首先执行 data-dismiss 并且永远不会调用控制器范围定义的函数。我花了一个小时来解决这个问题。

                【讨论】:

                  【解决方案19】:

                  我遇到的一个问题(可能对某人有帮助)只是我使用部分加载模态。

                  <li data-toggle="modal" data-target="#priceInfoModal">
                  <label>Listing Price</label>
                  <i class="fa fa-money"></i>
                  @Html.Partial("EditPartials/PriceInfo_Edit")
                  </li>
                  

                  我已将部分调用放在同一个列表项中 所以 data-target="#priceInfoModal" 和 div id="priceInfoModal" 在同一个容器中导致我无法关闭我的模式

                  【讨论】:

                    【解决方案20】:

                    因此,如果您不想移除淡入淡出或修改 dom 对象,您所要做的就是确保等待节目结束:

                    $('#load-modal').on('shown.bs.modal', function () {
                        console.log('Shown Modal Backdrop');
                        $('#load-modal').addClass('shown');
                    });
                    
                    function HideLoader() {
                        var loadmodalhidetimer = setInterval(function () {
                            if ($('#load-modal').is('.shown')) {                
                                $('#load-modal').removeClass('shown').modal('hide');
                                clearInterval(loadmodalhidetimer);
                                console.log('HideLoader');
                            }
                            else { //this is just for show.
                                console.log('Waiting to Hide');
                            }
                        }, 200);
                    }
                    

                    IMO Bootstrap 应该已经这样做了。好吧,也许还有一点,如果你有可能在没有完成 show 的情况下调用 hide,你可能想在 show.bs.modal 上添加一点,添加类 'showing' 并确保计时器检查显示是在进入循环之前打算。确保在显示的位置清除“显示”。

                    【讨论】:

                      【解决方案21】:

                      我遇到了同样的问题,解决方法是添加属性 data-dismiss="modal" 到你要点击的按钮。

                      【讨论】:

                        【解决方案22】:

                        data-backdrop="false" 选项作为属性添加到打开模式的按钮。

                        How to remove bootstrap modal overlay?

                        【讨论】:

                          【解决方案23】:

                          使用下面的代码,每次打开和关闭模态框时,都会在 body 元素上不断添加 7px 的内边距。

                          $('modalId').modal('hide');
                          $('body').removeClass('modal-open');
                          $('.modal-backdrop').remove();`
                          

                          对于仍在使用 Bootstrap 3 的用户,这里有一个 hack'ish 解决方法。

                          $('#modalid').modal('hide');
                          $('.modal-backdrop').hide();
                          document.body.style.paddingRight = '0'
                          document.getElementsByTagName("body")[0].style.overflowY = "auto";
                          

                          【讨论】:

                            【解决方案24】:

                            只需创建一个事件调用如下。在我使用 Angular 的情况下,只需放入 NgOnInit。

                            let body = document.querySelector('.modal-open');
                            body.classList.remove('modal-open');
                            body.removeAttribute('style');
                            let divFromHell = document.querySelector('.modal-backdrop');
                            body.removeChild(divFromHell);
                            

                            【讨论】:

                              【解决方案25】:

                              如果关闭关闭按钮正在工作,但在使用 modal('hide') 等动态代码时出现问题,则可以使用此代码。强制背景完全移除。

                              对于引导程序 3

                              $modal.on('hidden.bs.modal', function(){
                                //remove the backdrop
                                jQuery('[data-dismiss="modal"]').click();
                              });
                              
                              yourbutton.click(function() {
                                $modal.modal('hide');
                              });
                              

                              【讨论】:

                              • 请添加解释,突出显示解决 OP 问题的部分答案,以及为什么/如何。仅代码的答案在 SO 上不受欢迎。添加细节可以增加长期价值,并帮助未来的访问者学习,因此他们可以将这些知识应用于自己的编码问题。此外,它提高了答案的质量,因此也是如此。更高质量的答案得到更多人的支持,因为更多的用户发现它们更适合作为参考资源。
                              【解决方案26】:

                              这适用于在尝试了上面列出的几乎所有内容后无法修复的人。请去做一些基本的检查,比如脚本的顺序,引用它们等等。 就个人而言,我使用了 bootstrap 中的一个捆绑包,但由于某种原因它无法正常工作。切换到单独的脚本让我的生活轻松多了。 嗯是的!以防万一。

                              【讨论】:

                                【解决方案27】:

                                不使用 AJAX,但也在这里为其他使用 live demo Modal for Bootstrap 5 的人发帖。将 onClick 事件分配给 Save Changes 按钮后,您可以单击它,模态框将关闭,但背景将保留。

                                data-bs-dismiss="modal" 添加到“保存更改”按钮会导致在模式关闭时正确移除背景。

                                来自 Bootstrap 网站的原始代码:

                                <div class="modal-footer">
                                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                                        <button type="button" class="btn btn-primary">Save changes</button>
                                      </div>
                                

                                按预期工作的版本:

                                <div class="modal-footer">
                                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                                        <button type="button" class="btn btn-primary" data-bs-dismiss="modal" onClick={(e) => { doSomething(e) }}>Save changes</button>
                                      </div>
                                

                                【讨论】:

                                  猜你喜欢
                                  • 2015-08-15
                                  • 2014-06-16
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2013-05-05
                                  • 2015-03-14
                                  相关资源
                                  最近更新 更多