【问题标题】:bootstrap 3 close Modal when pushing browser back button按下浏览器后退按钮时引导 3 关闭模式
【发布时间】:2016-10-28 23:37:46
【问题描述】:

我只想使用引导程序 3 创建一个模式页面,该页面的行为与按下浏览器后退按钮或模式内的关闭按钮相同。我找到了一个可以执行此操作的脚本,但是有一个问题。假设我从 google.com 开始,进入这个模态页面,然后按下“模态!”按钮,然后按浏览器后退按钮,它将关闭模式,如果我再次按后退按钮,它将带我回到 google.com(一切都很好)。但是这一次,如果我打开模式页面并使用“关闭”按钮关闭模式。但现在,我必须按两次后退按钮才能返回 google.com。如果我使用模态内部的关闭按钮打开和关闭模态 10 倍。我发现我必须再按 10 次浏览器返回按钮才能返回 google.com 页面。如何解决这个问题? TIA

<!--html, bootstrap 3.2.0-->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
  <div class="modal-body">
    <p>If you press the web browser's back button not the modal's "close" button, the modal will close and the hash "#myModal" will be removed for the URL</p>
  </div>
  <div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Close</button></div>
</div>
</div>
</div>

<!--jquery-->
$('#myModal').on('show.bs.modal', function (e) {
    window.history.pushState('forward', null, '#modal');
});

$('#myModal').on('hide.bs.modal', function (e) {
    //pop the forward state to go back to original state before pushing the "Modal!" button
});

$(window).on('popstate', function () {
    $('#myModal').modal('hide');
});

jsfiddle source

【问题讨论】:

  • 你在模态隐藏事件中尝试过window.history.back();吗?
  • 我试过了,它没有关闭模式,而是完全访问 google.com。
  • 我认为发生这种情况是因为当您关闭模态时,window.history.back(); 会触发一个弹出状态,这会触发模态再次关闭,从而触发另一个 window.history.back()
  • 所以,它开始了。也许,在某些条件下使用它可以带来你的结果。尝试调试历史记录。你也可以看看这里:html5doctor.com/history-api
  • 感谢您的所有评论,这些评论澄清了正在发生的事情。这花了一些时间,但帮助我得出了我的解决方案。谢谢!

标签: jquery bootstrap-modal browser-history


【解决方案1】:

我知道这个问题是在 2016 年提出的,现在已经是 2020 年了,但我仍然要回答这个问题,以便那些将来可能会搜索它的人(我相信人们会)。

这是解决此问题的一站式解决方案。只需将以下代码复制并粘贴到您网站的 .js 文件(如 custom.js)中,或直接粘贴到 $(document).ready(function(){}) 中的页脚中即可

$(document).ready(function(){
  $('div.modal').on('show.bs.modal', function() {
    var modal = this;
    var hash = modal.id;
    window.location.hash = hash;
    window.onhashchange = function() {
      if (!location.hash){
        $(modal).modal('hide');
      }
    }
  });
  $('div.modal').on('hidden.bs.modal', function() {
    var hash = this.id;
    history.replaceState('', document.title, window.location.pathname);
  });
  // when close button clicked simulate back
  $('div.modal button.close').on('click', function(){
    window.history.back();
  })
  // when esc pressed when modal open simulate back
  $('div.modal').keyup(function(e) {
    if (e.keyCode == 27){
      window.history.back();          
    }
  });
});

我看到很多人都在寻找解决方案,现在我正在对搜索应用句号。这应该是我们一直在等待的确切工作“在点击 PC 和移动设备上的后退按钮以及在移动设备上的返回滑动手势时关闭引导模式(已测试)”。随意根据您的需要对其进行自定义。快乐的一天:)

【讨论】:

  • 太棒了,但不要用 window.location.pathname 替换整个路径,而是应该替换完整的 URL,而不是像 window.location.href 那样,以避免 URL 中的 GET 参数丢失
  • 如果您正在使用 Ruby on Rails 应用程序,您应该使用 $(document).on('turbolinks:load', function() { 作为第一行
  • 这仅在您第一次单击后退按钮关闭模式时才能正常工作。如果在同一个页面上多次打开模态框,是否需要多次点击后退才能关闭模态框?我也通过下面的@a55 解决方案得到了这种行为
  • 这不起作用。在我多次打开和关闭后,我必须多次单击返回按钮才能退出页面。感谢您的尝试。
【解决方案2】:

您可以使用以下代码来摆脱打开的模式窗口,而不是意外移动到浏览器的上一页。

//When ever the modal is shown the below code will execute.
$(".modal").on("shown.bs.modal", function()  {
    var urlReplace = "#" + $(this).attr('id'); 
    history.pushState(null, null, urlReplace); 
  });

  // This code gets executed when the back button is clicked, hide any/open modals.
  $(window).on('popstate', function() { 
    $(".modal").modal('hide');
  });

编辑:- 来自回复解决方案

$(".modal").on("hidden.bs.modal",function(){history.back(1);});

【讨论】:

  • 这和我原来的问题有同样的问题,我打开和关闭模式 4 次,我必须再点击 4 次后退按钮才能回到初始页面,所以这不是好的。感谢您的尝试。
  • 您可以通过设置计数器和使用 history.forward() 来改进此解决方案
  • 谢谢,加$(".modal").on("hidden.bs.modal",function(){history.back(1);});
  • 好多了。干杯@ShehrozAhmed
  • 这不起作用。在我多次打开和关闭后,我必须多次单击返回按钮才能退出页面。感谢您的尝试。
【解决方案3】:

我将此代码用于我自己的网站

window.onload=function(){

    State=popset=0;
    setpops=function(){
        if(popset) return;popset=1;// dont set event multiple times
        window.onpopstate=function(e){
            State=e.state;
            if(e.state=="hide"){
                $(".modal").modal("hide").removeClass("in show");
                $(".modal-backdrop").remove();// force hide bg
                /* in some old devices .modal("hide") is not enough */
            }
        };
    };

    $(".modal")
    .on("show.bs.modal",function(){// while modal show
        path=window.location.pathname+window.location.search;
        history.pushState("hide",null,path);
        history.pushState("show",null,path);
        State="show";
    })
    .on("hidden.bs.modal",function(){// while modal hide
        if(!!State)
            history.go(State=="hide"?-1:-2);// remove extra forward states
    });

    window.onpopstate=function(){setpops();};

    setTimeout(function(){setpops();},2000);// fix old webkit bug

};
  • 不要使用$(document).ready 而不是window.onload

Chrome 87、FireFox 84、Chromium 88、Android 4.1 / 4.2 / 7.1 / 9.0 上测试

(我是 user5490177 已删除帐号,回答 same question,这是一个新的改进版本)

【讨论】:

  • 这仅在您第一次单击后退按钮关闭模式时才能正常工作。如果在同一个页面多次打开modal,是否需要多次点击后退才能关闭modal?
  • @digital-fusion 因为$(".modal") 包含页面上的所有模态类,然后如果按下返回按钮1次,它将关闭所有模态
  • 对不起,我指的不是多模态。如果我使用此代码加载页面并打开模式,然后单击后退按钮,模式将关闭。如果我然后再次打开模态并单击后退按钮,则模态不会关闭(完全空白)。然后我必须再次单击返回按钮才能将其关闭。
  • 这种行为似乎是由于在模式中使用了 iframe,并通过打开模式的按钮中的 onClick 事件将 URL 加载到 iframe 中。当模式关闭时,iframe 源设置回 about:blank。令人困惑的是,为什么在您第一次打开模式时会起作用,然后所有后续打开都需要单击两次才能关闭它
  • 太棒了!即使我无法完全理解您的逻辑,但即使在 jsfiddle 上,此解决方案也有效!经过这么多年,终于有了一个可行的解决方案,我可以给我的“复选”标记。谢谢!
【解决方案4】:

我找到了解决方案。随意发布任何其他优雅的解决方案。

$('#myModal').on('hide.bs.modal', function (e) {
    if(location.hash=='#modal')window.history.back();
});

$(window).on('popstate', function (event) {  //pressed back button
    if(event.state!==null)$('.modal').modal('hide');
});

【讨论】:

  • 注意,这个解决方案不适用于 jsfiddle,因为 jsfiddle 不做哈希。它将在常规页面上工作。我也希望有人能提出更优雅的解决方案,它不需要任何额外的插件并且可以在任何东西上工作,即使在 jsfiddle 上也是如此。这就是为什么我不接受我自己的解决方案,即使它有效。
【解决方案5】:

点击按钮会弹出。

$(document).ready(function(){
      $(".popup-btn").click(function () {
          location.hash = "popup";
          $(".popup-panel").show();
      });
});

在位置更改时它会被隐藏:

$(window).bind('hashchange', function () {
      if (location.hash == null || location.hash == "") {
          $(".popup-panel").hide();
      }
});

【讨论】:

  • 我认为这是可行的,但是浏览器的后退按钮会完全退出页面,而不是仅仅关闭模式。我需要浏览器后退按钮来关闭模式,就像按下模式“关闭”按钮一样,而不离开页面。感谢您的尝试。
猜你喜欢
  • 1970-01-01
  • 2016-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
  • 1970-01-01
  • 2021-07-26
相关资源
最近更新 更多