如何防止关闭浏览器窗口?

IT技术 javascript browser window onbeforeunload
2021-02-11 02:43:58

我尝试了以下代码以在关闭浏览器窗口时收到警报:

window.onbeforeunload = confirmExit;
function confirmExit() {
  return "You have attempted to leave this page.  If you have made any changes to the fields without clicking the Save button, your changes will be lost.  Are you sure you want to exit this page?";
}

它可以工作,但如果页面包含一个超链接,则单击该超链接会引发相同的警报。我只需要在关闭浏览器窗口时显示警报,而不是在单击超链接时显示。

4个回答

另一个实现如下,您可以在此网页中找到它:http : //ujap.de/index.php/view/JavascriptCloseHook

<html>
  <head>
    <script type="text/javascript">
      var hook = true;
      window.onbeforeunload = function() {
        if (hook) {
          return "Did you save your stuff?"
        }
      }
      function unhook() {
        hook=false;
      }
    </script>
  </head>
  <body>
    <!-- this will ask for confirmation: -->
    <a href="http://google.com">external link</a>

    <!-- this will go without asking: -->
    <a href="anotherPage.html" onClick="unhook()">internal link, un-hooked</a>
  </body>
</html>

它的作用是将变量用作标志。

@netadictos 我建议您更新您的答案以使用更现代的.addEventListener()而不是onclick属性(或.onbeforeunload = ...)。
2021-03-23 02:43:58
我建议您不要使用 addEventListener,因为 onclick 在所有浏览器中都有效。您仍然可以不显眼地分配 onclick
2021-04-03 02:43:58
@mplungjan 实际上,addEventListener 适用于所有浏览器。如果您认为 IE <= 8 也是一个浏览器,您可以使用attachEvent具有基本相同功能的方法。
2021-04-05 02:43:58
根据您的解决方案,我建议如果您使用 jQuery,请使用类似 .noConfirm 的类并执行以下操作: $('.noConfirm').click(unhook)
2021-04-07 02:43:58
+1 因为它是更通用且易于访问的解决方案。假设我有一个进行页面重定向的脚本部分,因此在应用重定向操作之前,我只需设置hook = false. 结帐这个演示
2021-04-09 02:43:58

保持代码不变并使用 jQuery 处理链接:

$(function () {
  $("a").click(function {
    window.onbeforeunload = null;
  });
});
这个问题没有 jQuery 标签。
2021-03-17 02:43:58
@M.UtkuALTINKAYA 你是什么意思?这个问题仍然没有 jQuery 标签。
2021-03-23 02:43:58
@M.UtkuALTINKAYA 他的意思是这个问题没有 jQuery 标签,所以你不应该用 jQuery 解决方案来回答。Vanilla javascript 会是最好的。
2021-03-27 02:43:58
是的,它适用于链接,但请提供一个解决方案,当我们刷新浏览器时,window.onbeforeunload 事件触发器我们如何才能停止在刷新页面上触发事件或按后退按钮,您对此有何想法
2021-03-29 02:43:58
如果打开的子窗口在另一个域中,这是否有效?
2021-04-05 02:43:58

您可以检测超链接的点击次数,但无法确定用户是否:

  • 尝试刷新页面。
  • 试图关闭浏览器选项卡。
  • 试图关闭浏览器窗口。
  • 在 URL 栏中输入另一个 URL 并按 Enter。

所有这些操作都会beforeunload在 上生成事件window,而没有关于该事件的任何更准确的信息。

为了在执行上述操作时显示确认对话框,并且在单击超链接时不显示它,请按照下列步骤操作:

  • beforeunload事件侦听器分配window,它将以字符串形式返回确认文本,除非将特定变量(标志)设置为true
  • click事件分配document. 检查a元素是否已被单击 ( event.target.tagName)。如果是,将标志设置为true

您还应该通过为 分配一个submit事件侦听器来处理表单提交document

您的代码可能如下所示:

let disableConfirmation = false;
window.addEventListener('beforeunload', event => {
  const confirmationText = 'Are you sure?';
  if (!disableConfirmation) {
    event.returnValue = confirmationText; // Gecko, Trident, Chrome 34+
    return confirmationText;              // Gecko, WebKit, Chrome <34
  } else {
    // Set flag back to false, just in case
    // user stops loading page after clicking a link.
    disableConfirmation = false;
  }
});
document.addEventListener('click', event => {
  if (event.target.tagName.toLowerCase() === 'a') {
    disableConfirmation = true;
  }
});
document.addEventListener('submit', event => {
  disableConfirmation = true;
});
<p><a href="https://stacksnippets.net/">google.com</a></p>
<form action="https://stacksnippets.net/"><button type="submit">Submit</button></form>
<p>Try clicking the link or the submit button. The confirmation dialog won't be displayed.</p>
<p>Try reloading the frame (right click -> "Reload frame" in Chrome). You will see a confirmation dialog.</p>

请注意,在某些浏览器,你必须使用event.returnValuebeforeunload监听器,而在其他你使用return的语句。

另请参阅beforeunload事件文档

我添加了一个额外的代码来处理窗口关闭时的进一步处理

let disableConfirmation = false;
window.addEventListener('beforeunload', event => {
  const confirmationText = 'Are you sure?';
  if (!disableConfirmation) {
    event.returnValue = confirmationText; // Gecko, Trident, Chrome 34+
    return confirmationText;              // Gecko, WebKit, Chrome <34
  } else {
    // Set flag back to false, just in case
    // user stops loading page after clicking a link.
    disableConfirmation = false;
  }
});

如果你想发送任何ajax请求并且你已经使用了jquery,那么在确认之后

 $(window).on('unload', function() {
   // async: false will make the AJAX synchronous in case you're using jQuery
   axios
     .get('ajax_url')
     .then(response => {});
 });

如果没有使用 jquery,你可以使用导航器,它需要导航器库

navigator.sendBeacon(url, data);

你可以从这里下载这个库:https : //github.com/miguelmota/Navigator.sendBeacon