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

4 回答 4

51

另一个实现如下,您可以在此网页中找到它: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>

它的作用是使用变量作为标志。

于 2008-12-02T11:20:11.037 回答
32

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

$(function () {
  $("a").click(function {
    window.onbeforeunload = null;
  });
});
于 2008-12-02T11:19:28.667 回答
6

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

  • 试图刷新页面。
  • 试图关闭浏览器选项卡。
  • 试图关闭浏览器窗口。
  • 在 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.returnValuein beforeunloadlistener,而在其他浏览器中您必须使用returnstatement。

另请参阅beforeunload事件文档

于 2016-01-12T22:45:41.757 回答
2

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

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,那么在 Confimation 之后

 $(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,它需要 navigator 库

navigator.sendBeacon(url, data);

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

于 2020-07-08T08:32:18.047 回答