【问题标题】:When modal popup is open, prevent mobile "Back button" to quit the site, close the popup instead当模式弹出窗口打开时,防止移动“返回按钮”退出站点,而是关闭弹出窗口
【发布时间】:2018-04-23 05:03:01
【问题描述】:

当打开一个模态弹出对话框时,即使我添加了一个关闭按钮(通常是右上角的 X),一些手机用户也会使用他们的手机“后退按钮”来关闭弹出窗口。但相反,这将退出网站!

如何让移动端的“返回按钮”关闭弹窗而不是退出网站?

document.getElementById("link").onclick = function(e) {
  e.preventDefault();
  document.getElementById("popupdarkbg").style.display = "block";
  document.getElementById("popup").style.display = "block";
    document.getElementById('popupdarkbg').onclick = function() {
      document.getElementById("popup").style.display = "none";
      document.getElementById("popupdarkbg").style.display = "none";
  };
  return false;
}
#popup { display: none; position: fixed; top: 12%; left: 15%; width: 70%; height: 70%; background-color: white; z-index: 10; }
#popupdarkbg { position: fixed; z-index: 5; left: 0; top: 0; width: 100%; height: 100%; overflow: hidden; background-color: rgba(0,0,0,.75); display: none; }
<div id="main">
<a href="" id="link">Click me</a><br>
</div>
<div id="popup">This is a popup window! Click mobile "Back button"</div>
<div id="popupdarkbg"></div>

注意事项:

  • 我已经看过这个 Codepen How to disable browser back button using JavaScript,但我不确定它是否可以在 Chrome、Firefox、Safari 和 Android、iOS 等上跨浏览器。

  • 我已经看到有关 window.onpopstate = function () { history.go(1); }; 的答案,但我想确保这是在这里做的好习惯,(所以它不是它们的重复)。

【问题讨论】:

  • pushState 在各种浏览器和平台上都得到了很好的支持,这种方法是一种常见的做法。除非您专门针对 IE9 或更低版本,否则一切正常。
  • @MátéSafranka 所以你会只在弹出窗口打开时做window.onpopstate = function () { history.go(1); };,在弹出窗口关闭时做window.onpopstate = function () { };(或其他什么?)这样,当弹出窗口关闭时,他们仍然可以去返回上一个网站?

标签: javascript responsive-design modal-dialog back-button


【解决方案1】:

这是我在应用程序中的粗略版本:

var showModal = function() {
    // some code here to show the HTML elements...

    window.history.pushState('backPressed', null, null);
    window.history.pushState('dummy', null, null);
    window.addEventListener('popstate', hideModal, { once: true });
};

var hideModal = function(event) {
    if (event.state == 'backPressed') {
        // hide the HTML elements
    }
};

我添加两个虚拟状态的原因是因为popstate 事件也会在 URL 哈希更改时触发,例如当用户在地址栏中手动覆盖哈希时。检查当前历史状态是否匹配 backPressed 让我验证事件确实是由返回按钮触发的。

【讨论】:

  • 非常感谢。例如,当在 Chrome for Android 中使用它时,它现在可以工作,但在从应用程序中使用时就不行了(我的应用程序只是一个显示网站的 Android WebView:后退按钮退出应用程序)。
  • 啊,好吧,恐怕我无法确定地帮助你。根据我对 Android 开发人员的记忆,您可能需要在 Android 应用程序本身中捕获 Back 事件,然后使用 WebView 对象的 API 以某种方式通知内部的 JS 代码。我的猜测(查看 WebView 的 Android 参考)是调用 goBack() 来模拟浏览器的后退按钮。
  • 再次非常感谢!注:Android WebView部分已直接解决by this answer
【解决方案2】:

这是我最终使用的已接受答案 (*) 的一个小变体:

window.history.pushState('popupclosed', null, null);    // initial state: closed

var hideModal = function(event) {
    if (event.state == 'popupclosed') {
        closepopup();
    }
};

var showModal = function(event) {
    if (history.state !== 'opened') {
        window.history.pushState('opened', null, null);
    }
    window.addEventListener('popstate', hideModal, { once: true });   

与 (*) 的区别在于:

  • 我们只在浏览器历史记录中为每个弹出窗口添加 1 个新状态,而不是 2 个

  • 如果上一个弹出窗口是用弹出窗口的 X 右上角按钮关闭的(但不使用“历史上的上一个”浏览器按钮或手机上的“后退按钮”),然后 在打开时第二个弹出窗口,不要重新创建新的历史状态opened,因为它已经是当前状态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-28
    • 2013-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多