如何*动态*在卸载监听器之前添加/删除(警告未保存的更改)

问题描述 投票:0回答:1

根据Google的Page Lifecycle API,有两种模式可警告用户未保存的更改。

  1. [不推荐Page Lifecycle API提供(无条件添加beforeunload侦听器):
addEventListener('beforeunload', (event) => {
  // A function that returns `true` if the page has unsaved changes.
  if (pageHasUnsavedChanges()) {
    event.preventDefault();
    return event.returnValue = 'Are you sure you want to exit?';
  }
}, {capture: true});
  1. [推荐Page Lifecycle API(动态添加/删除beforeunload侦听器):
const beforeUnloadListener = (event) => {
  event.preventDefault();
  return event.returnValue = 'Are you sure you want to exit?';
};

// A function that invokes a callback when the page has unsaved changes.
onPageHasUnsavedChanges(() => {
  addEventListener('beforeunload', beforeUnloadListener, {capture: true});
});

// A function that invokes a callback when the page's unsaved changes are resolved.
onAllChangesSaved(() => {
  removeEventListener('beforeunload', beforeUnloadListener, {capture: true});
});

但是我们实际上如何从方法#1转换为推荐的方法#2?


方法#1的有效MWE,其中pageHasUnsavedChanges()是使用jQuery serialize()实现的,beforeunload侦听器是方法#1的直接复制粘贴:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
  </head>

  <body>
    <form>
      <input name="input">
      <button type="submit">Submit</button>
    </form>

    <script>
      // set initial state
      const getState = () => $('form').serialize();
      const state = getState();

      // add unconditional listener
      addEventListener('beforeunload', (event) => {
        if(state != getState()) {
          event.preventDefault();
          return event.returnValue = 'Are you sure you want to exit?';
        }
      }, {capture: true});
    </script>
  </body>
</html>

如果用推荐的addEventListener /beforeUnloadListener/ onPageHasUnsavedChanges代码替换onAllChangesSaved块,它只是告诉我on*引用未定义。

  • onPageHasUnsavedChangesonAllChangesSaved来自哪里?
  • 或者,如果我们应该自己编写它们,将这种MWE转换为推荐的方法2的方法是什么?

方法2的MWE损坏:https://tdy.github.io/beforeunload/

在表单更改时,我根据beforeUnloadListener是否与state相匹配来添加/删除getState()

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js">/script>
  </head>

  <body>
    <form>
      <input name="input">
      <button type="submit">Submit</button>
    </form>

    <script>
      // set initial state
      const getState = () => $('form').serialize();
      const state = getState();

      // save listener
      const beforeUnloadListener = (event) => {
        event.preventDefault();
        return event.returnValue = 'Are you sure you want to exit?';
      };

      // add/remove saved listener on form change
      $('form').change(() => {
        if(state != getState()) {
          addEventListener('beforeunload', beforeUnloadListener, {capture: true});
        } else {
          removeEventListener('beforeunload', beforeUnloadListener, {capture: true});
        }
      });
    </script>
  </body>
</html>
javascript jquery onbeforeunload page-lifecycle
1个回答
0
投票

注意:PageLifecycle.js库提供了便捷方法addUnsavedChanges()removeUnsavedChanges(),它们遵循上述所有最佳实践。它们基于提议的草稿,该正式草稿用声明性API正式取代了beforeunload事件,该API在移动平台上不易被滥用且更可靠。

[如果您想以跨浏览器的方式正确使用beforeunload事件,则我们建议您使用PageLifecycle.js库。

从页面生命周期API页面开始。

© www.soinside.com 2019 - 2024. All rights reserved.