Как я могу переопределить диалог OnBeforeUnload и заменить его своим собственным?
Мне нужно предупредить пользователей о несохраненных изменениях, прежде чем они покинут страницу (довольно распространенная проблема).
window.onbeforeunload=handler
Это работает, но вызывает диалоговое окно по умолчанию с раздражающим стандартным сообщением, которое оборачивает мой собственный текст. Мне нужно либо полностью заменить стандартное сообщение, чтобы мой текст был чистым, либо (что еще лучше) заменить весь диалог модальным диалогом с использованием jQuery.
Пока что я потерпел неудачу, и я не нашел никого, кто, кажется, имеет ответ. Это вообще возможно?
Javascript на моей странице:
<script type="text/javascript">
window.onbeforeunload=closeIt;
</script>
Функция closeIt():
function closeIt()
{
if (changes == "true" || files == "true")
{
return "Here you can append a custom message to the default dialog.";
}
}
Используя jQuery и jqModal, я пробовал подобные вещи (используя пользовательский диалог подтверждения):
$(window).beforeunload(function() {
confirm('new message: ' + this.href + ' !', this.href);
return false;
});
который также не работает - я не могу связываться с событием beforeunload.
14 ответов
Вы не можете изменить диалог по умолчанию для onbeforeunload
Поэтому лучше всего работать с ним.
window.onbeforeunload = function() {
return 'You have unsaved changes!';
}
Вот ссылка на это от Microsoft:
Когда строка присваивается свойству returnValue файла window.event, появляется диалоговое окно, которое дает пользователям возможность остаться на текущей странице и сохранить назначенную ей строку. Оператор по умолчанию, который появляется в диалоговом окне "Вы уверены, что хотите отойти от этой страницы? ... Нажмите OK, чтобы продолжить, или Отмена, чтобы остаться на текущей странице.", Нельзя удалить или изменить.
Кажется, проблема в следующем:
- когда
onbeforeunload
вызывается, это будет принимать возвращаемое значение обработчика какwindow.event.returnValue
, - Затем он будет анализировать возвращаемое значение как строку (если оно не равно нулю).
- поскольку
false
анализируется как строка, диалоговое окно будет запущено, которое затем передаст соответствующийtrue
/false
,
В результате, кажется, нет способа назначить false
в onbeforeunload
чтобы предотвратить это из диалога по умолчанию.
Дополнительные примечания по jQuery:
- Установка события в jQuery может быть проблематичной, так как это позволяет другим
onbeforeunload
события должны произойти также. Если вы хотите, чтобы произошло событие unload, я бы остановился на обычном JavaScript. У jQuery нет ярлыка для
onbeforeunload
так что вам придется использовать общийbind
синтаксис.$(window).bind('beforeunload', function() {} );
Изменить 09/04/2018: пользовательские сообщения в диалогах onbeforeunload устарели начиная с chrome-51 (см. Примечание к выпуску)
Оуэн прав. И причина этого заключается в безопасности. Предотвращение выгрузки страницы полезно в веб-формах и тому подобном, но злоумышленник может легко использовать ее, чтобы обмануть пользователя, чтобы он остался на странице. Вот почему веб-браузеры реализуют стандартное сообщение и имеют этот механизм для вставки пользовательского текста.
Что сработало для меня, используя jQuery и протестировано в IE8, Chrome и Firefox, так это:
$(window).bind("beforeunload",function(event) {
if(hasChanged) return "You have unsaved changes";
});
Важно ничего не возвращать, если подсказка не требуется, поскольку здесь есть различия между IE и другими режимами работы браузера.
Хотя в некоторых случаях вы ничего не можете сделать с этим ящиком, вы можете перехватить кого-нибудь, щелкнув по ссылке. Для меня это стоило усилий для большинства сценариев, и как запасной вариант, я оставил событие unload.
Я использовал Boxy вместо стандартного диалога jQuery, он доступен здесь: http://onehackoranother.com/projects/jquery/boxy/
$(':input').change(function() {
if(!is_dirty){
// When the user changes a field on this page, set our is_dirty flag.
is_dirty = true;
}
});
$('a').mousedown(function(e) {
if(is_dirty) {
// if the user navigates away from this page via an anchor link,
// popup a new boxy confirmation.
answer = Boxy.confirm("You have made some changes which you might want to save.");
}
});
window.onbeforeunload = function() {
if((is_dirty)&&(!answer)){
// call this if the box wasn't shown.
return 'You have made some changes which you might want to save.';
}
};
Вы можете присоединиться к другому событию и отфильтровать больше информации о том, на какой вид якоря щелкнули, но это работает для меня и того, что я хочу сделать, и служит примером для использования или улучшения другими. Думал, что поделюсь этим для тех, кто хочет это решение.
Я вырезал код, так что это может не работать как есть.
1) Используйте перед загрузкой, а не загрузкой.
2) Важно избегать выполнения оператора return. Я не имею в виду, чтобы избежать возвращения из вашего обработчика. Вы возвращаете все правильно, но вы делаете это, гарантируя, что вы достигли конца функции и НЕ выполняете инструкцию возврата. При этих условиях встроенный стандартный диалог не происходит.
3) Если вы используете onbeforeunload, вы можете запустить ajax-вызов в своем обработчике unbeforeunload, чтобы привести в порядок сервер, но он должен быть синхронным, и вам придется ждать и обрабатывать ответ в своем обработчике onbeforeunload (все еще соблюдая условие (2) выше). Я делаю это, и это прекрасно работает. Если вы делаете синхронный вызов ajax, все задерживается до тех пор, пока ответ не вернется. Если вы делаете асинхронный ответ, думая, что вам не нужен ответ от сервера, выгрузка страницы продолжается, и ваш ajax-вызов прерывается этим процессом - включая удаленный скрипт, если он выполняется.
Подход Angular 9:
constructor() {
window.addEventListener('beforeunload', (event: BeforeUnloadEvent) => {
if (this.generatedBarcodeIndex) {
event.preventDefault(); // for Firefox
event.returnValue = ''; // for Chrome
return '';
}
return false;
});
}
Поддержка браузеров и удаление настраиваемого сообщения:
- Chrome убрал поддержку пользовательского сообщения в версии 51 мин.
- Opera удалила поддержку пользовательского сообщения в версии 38 мин.
- Firefox удалил поддержку пользовательского сообщения в версии 44.0 мин.
- Safari удалила поддержку пользовательского сообщения в версии 9.1 мин.
Это не может быть сделано в Chrome сейчас, чтобы избежать спама, обратитесь к javascript onbeforeunload, не показывающему пользовательское сообщение для получения дополнительной информации.
Попробуйте разместить return;
вместо сообщения.. это работает большинство браузеров для меня.
(Это только действительно мешает подаркам диалога)
window.onbeforeunload = function(evt) {
//Your Extra Code
return;
}
Я столкнулся с той же проблемой, я был в порядке, чтобы получить свое собственное диалоговое окно с моим сообщением, но проблема, с которой я столкнулся, была: 1) Он давал сообщение на всех навигациях, я хочу это только для близкого щелчка. 2) с моим собственным подтверждающим сообщением, если пользователь выбирает "Отмена", оно по-прежнему отображает диалоговое окно браузера по умолчанию.
Ниже приведен код решения, который я нашел и написал на своей главной странице.
function closeMe(evt) {
if (typeof evt == 'undefined') {
evt = window.event; }
if (evt && evt.clientX >= (window.event.screenX - 150) &&
evt.clientY >= -150 && evt.clientY <= 0) {
return "Do you want to log out of your current session?";
}
}
window.onbeforeunload = closeMe;
Вы можете определить, какая кнопка (ок или отмена) нажата пользователем, потому что функция onunload вызывается только тогда, когда пользователь выбирает покинуть страницу. Хотя в этой функции возможности ограничены, потому что DOM рушится. Вы можете запустить javascript, но ajax POST ничего не делает, поэтому вы не можете использовать этот метод для автоматического выхода из системы. Но для этого есть решение. Window.open('logout.php') выполняется в функции onunload, поэтому пользователь выходит из системы с открытием нового окна.
function onunload = (){
window.open('logout.php');
}
Этот код вызывается, когда пользователь покидает страницу или закрывает активное окно, и пользователь выходит из системы с помощью logout.php. Новое окно закрывается сразу, когда выход php состоит из кода:
window.close();
Попробуй это
$(window).bind('beforeunload', function (event) {
setTimeout(function () {
var retVal = confirm("Do you want to continue ?");
if (retVal == true) {
alert("User wants to continue!");
return true;
}
else {
window.stop();
return false;
}
});
return;
});
Как насчет использования специализированной версии команды "связать" "один". Как только обработчик событий выполняется в первый раз, он автоматически удаляется как обработчик событий.
$(window).one("beforeunload", BeforeUnload);
<script type="text/javascript">
window.onbeforeunload = function(evt) {
var message = 'Are you sure you want to leave?';
if (typeof evt == 'undefined') {
evt = window.event;
}
if (evt) {
evt.returnValue = message;
}
return message;
}
</script>
обратитесь с http://www.codeprojectdownload.com/
У меня была такая же проблема, и она сводила меня с ума. Я хотел полностью избавиться от всплывающего окна, потому что я не хотел предупреждать пользователя - просто перенести их из формы на новую страницу. Я попробовал вышеуказанные ответы и не смог заставить их работать.
В конце концов, я получил это, чтобы игнорировать всплывающее окно Firefox по умолчанию, с помощью этого сайта: http://code-maven.com/prevent-leaving-the-page-using-plain-javascript. Это добавлено перед тем, как вы перенаправите окно:
window.onbeforeunload = function() {
if (data_needs_saving()) {
return "";
} else {
return "";
}
};
window.location.href = 'www.redirect here';