Как я могу переопределить диалоговое окно OnBeforeUnload и заменить его своим собственным?

StackOverflow https://stackoverflow.com/questions/276660

Вопрос

Мне нужно предупредить пользователей о несохраненных изменениях, прежде чем они покинут страницу (довольно распространенная проблема).

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.

Это было полезно?

Решение

Вы не можете изменить диалог по умолчанию для onbeforeunload, поэтому лучше всего работать с ним.

window.onbeforeunload = function() {
    return 'You have unsaved changes!';
}

Вот ссылка на это от Microsoft:

Когда строка присваивается свойству returnValue объекта window.event, появляется диалоговое окно, которое дает пользователям возможность остаться на текущей странице и сохранить назначенную ей строку.Оператор по умолчанию, который появляется в диалоговом окне: «Вы уверены, что хотите уйти с этой страницы?...Нажмите «ОК», чтобы продолжить, или «Отмена», чтобы остаться на текущей странице.», невозможно удалить или изменить.

Кажется, проблема в следующем:

  1. Когда onbeforeunload вызывается, он примет возвращаемое значение обработчика как window.event.returnValue.
  2. Затем он будет анализировать возвращаемое значение как строку (если оно не равно нулю).
  3. С false анализируется как строка, открывается диалоговое окно, которое затем передает соответствующий true/false.

В результате, похоже, нет способа назначить false к onbeforeunload чтобы предотвратить его появление в диалоге по умолчанию.

Дополнительные примечания по jQuery:

  • Установка события в jQuery может быть проблематичным, поскольку это позволяет другим onbeforeunload события тоже должны произойти.Если вы хотите, чтобы произошло только событие выгрузки, я бы придерживался для этого простого JavaScript.
  • jQuery не имеет ярлыка для onbeforeunload поэтому вам придется использовать общий bind синтаксис.

    $(window).bind('beforeunload', function() {} );
    

Редактировать 04.09.2018:пользовательские сообщения в диалоговых окнах onbeforeunload устарели, начиная с версии chrome-51 (см.: Release Note)

Другие советы

Что сработало для меня, используя 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) Используйте onbeforeunload, а не onunload.

2) Важно избегать выполнения оператора return. Я не имею в виду, чтобы избежать возвращения из вашего обработчика. Вы вернете все правильно, но вы сделаете это, убедившись, что достигли конца функции и НЕ выполняете инструкцию возврата. При этих условиях встроенный стандартный диалог не появляется.

3) Если вы используете onbeforeunload, вы можете запустить ajax-вызов в вашем обработчике unbeforeunload, чтобы привести в порядок сервер, но он должен быть синхронным, и вам придется ждать и обрабатывать ответ в своем обработчике onbeforeunload (все еще соблюдая условие (2) выше). Я делаю это, и это отлично работает. Если вы делаете синхронный вызов ajax, все задерживается до тех пор, пока ответ не вернется. Если вы делаете асинхронный запрос, думая, что вам не нужен ответ от сервера, выгрузка страницы продолжается, и ваш процесс ajax прерывается этим процессом, включая удаленный скрипт, если он выполняется.

Попробуйте разместить return; вместо сообщения ... это подходит большинству браузеров для меня. (Это действительно только предотвращает подарки от диалога)

window.onbeforeunload = function(evt) {            
        //Your Extra Code
        return;
}

Вы можете определить, какая кнопка (ок или отмена) нажата пользователем, потому что функция onunload вызывается только тогда, когда пользователь выбирает покинуть страницу. Хотя в этой функции возможности ограничены, потому что DOM рушится. Вы можете запустить javascript, но ajax POST ничего не делает, поэтому вы не можете использовать этот метод для автоматического выхода из системы. Но для этого есть решение. Window.open ('logout.php') выполняется в функции onunload, поэтому пользователь выходит из системы с открытием нового окна.

function onunload = (){
    window.open('logout.php');
}

Этот код вызывается, когда пользователь покидает страницу или закрывает активное окно и пользователь выходит из системы с помощью logout.php. Новое окно закрывается сразу, когда выход php состоит из кода:

window.close();

Я столкнулся с той же проблемой, я был в порядке, чтобы получить свое собственное диалоговое окно с моим сообщением, но проблема, с которой я столкнулся, была: 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;

Этого нельзя сделать в Chrome сейчас, чтобы избежать спама, см. javascript onbeforeunload не отображается пользовательское сообщение для получения дополнительной информации.

 <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

Как насчет использования специализированной версии " bind " команда "один". Как только обработчик событий выполняется в первый раз, он автоматически удаляется как обработчик событий.

$(window).one("beforeunload", BeforeUnload);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top