根据Google的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});
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*
引用未定义。
onPageHasUnsavedChanges
和onAllChangesSaved
来自哪里?方法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>
注意:PageLifecycle.js库提供了便捷方法
addUnsavedChanges()
和removeUnsavedChanges()
,它们遵循上述所有最佳实践。它们基于提议的草稿,该正式草稿用声明性API正式取代了beforeunload
事件,该API在移动平台上不易被滥用且更可靠。[如果您想以跨浏览器的方式正确使用
beforeunload
事件,则我们建议您使用PageLifecycle.js库。
从页面生命周期API页面开始。