Согласно Google Page Life API API , существует два шаблона для предупреждения пользователей о несохраненных изменениях.
- Не рекомендуется на странице 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});
Рекомендуется 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?
Работа MWE для метода # 1 , где 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
откуда? - Или если мы должны чтобы написать их самим, каков подход для преобразования этого MWE в рекомендованный метод # 2?
Сломанный MWE для метода # 2: 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>