window.beforeunload дважды вызывается в Firefox - как обойти это? - PullRequest
5 голосов
/ 26 ноября 2009

Я создаю всплывающее окно, в котором установлен обработчик beforeunload. Когда элемент меню «Закрыть» используется для закрытия всплывающего окна, обработчик beforeunload вызывается дважды, что приводит к двум «Вы уверены, что хотите закрыть это окно?» появляются сообщения.

Это ошибка в Firefox, и я сообщил об этом здесь , но я все же хотел бы найти способ предотвратить это. Можете ли вы придумать разумный способ обнаружения двойного перед загрузкой, чтобы предотвратить проблему двойного сообщения? Проблема в том, что Firefox не сообщает мне, какую кнопку в диалоге пользователь выбрал для щелчка - ОК или отмена.

Ответы [ 9 ]

2 голосов
/ 30 июня 2010
<script type="text/javascript">
var onBeforeUnloadFired = false;

window.onbeforeunload = function ()
{
    if (!onBeforeUnloadFired) {
        onBeforeUnloadFired = true;
        event.returnValue = "You have attempted to leave this page.  If you have made any changes to the fields without clicking the Save button, your changes will be lost.  Are you sure you want to exit this page?";
   }

   window.setTimeout("ResetOnBeforeUnloadFired()", 10);
}

function ResetOnBeforeUnloadFired() {
   onBeforeUnloadFired = false;
}    
</script>
1 голос
/ 19 августа 2012

Я обнаружил эту проблему в Chrome 21, Firefox 14, IE 7-9, Safari 5 (на ПК).

Следующее работает во всех этих браузерах. Если во время события удалить функцию window.onbeforeunload, это предотвратит второй вызов. Хитрость в том, чтобы сбросить функцию window.onbeforeunload, если пользователь решает остаться на странице.

var window_on_before_unload = function(e) {
    var msg;
    // Do here what you ever you need to do
    msg = "Message for user";

    // Prevent next "window.onbeforeunload" from re-running this code.
    // Ensure that if the user decides to stay on the page that
    // this code is run the next time the user tries to leave the page.
    window.onbeforeunload = set_on_before_unload;

    // Prepare message for user
    if (msg) {
        if (/irefox\/([4-9]|1\d+)/.test(navigator.userAgent))
            alert(msg
                    + '\n\nThe next dialog will allow you to stay here or continue\nSee Firefox bug #588292');

        (e = e || window.event).returnValue = msg;
        return msg;
    }
};

// Set window.onbeforeunload to the above handler.
// @uses window_on_before_unload
// @param {Event} e
var set_on_before_unload = function(e) {
    // Initialize the handler for window.onbeforeunload.
    window.onbeforeunload = window_on_before_unload;
}

// Initialize the handler for window.onbeforeunload.
set_on_before_unload();
1 голос
/ 07 апреля 2010

Лучшее решение, которое я нашел, - это использовать глобальную переменную flag, которая сбрасывается через много миллисекунд, скажем, 500 (это гарантирует, что функция может быть вызвана снова, но не сразу после ее появления).

См. Последний код в:

http://social.msdn.microsoft.com/Forums/en/sharepointinfopath/thread/13000cd8-5c50-4260-a0d2-bc404764966d

1 голос
/ 19 февраля 2010

Это определенно ошибка FF. Я сообщил об этом на https://bugzilla.mozilla.org/show_bug.cgi?id=531199

1 голос
/ 26 ноября 2009

Установите переменную в обработчике, чтобы предотвратить появление диалогового окна во второй раз. Используйте setTimeout, чтобы сбросить его потом.

0 голосов
/ 11 июля 2016

У меня есть документ, открывающий другое всплывающее окно с window.open. В исходном окне я зарегистрировал (с помощью jquery) прослушиватель события «unload», подобного этому:

var popup_window = window.open(...) 
$(popup_window).on('unload', function(event) ...

Я наткнулся на эту страницу, потому что это событие дважды срабатывало. Я обнаружил, что это не ошибка, она срабатывает дважды, потому что она запускается один раз, когда страница about: blank заменяется вашей страницей, а другая - при загрузке вашей страницы.

Все, что мне нужно сделать, это отфильтровать интересующее меня событие, запросив исходное событие:

function (event) {
   var original_url = e.originalEvent.originalTarget.URL;
   if (original_url != 'about:blank')
   {
       ... do cool things ...
   }
}

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

0 голосов
/ 23 ноября 2011

Я обнаружил, что вместо того, чтобы делать свой собственный вызов для подтверждения (), просто сделайте даже.preventDefault (); в событии beforeunload. Firefox открывает свой собственный диалог подтверждения. Я не уверен, что это правильно / стандартно, но вот как они это делают.

0 голосов
/ 22 мая 2011

Я использую следующий фрагмент для отслеживания exitcount

Когда страница загружается, инициализируется следующая переменная exitCount

if (typeof(MTG) == 'undefined') MTG = {};
MTG.exitCount=0; 

и в событии выгрузки окна

$(window).bind("beforeunload", function(){


            if (MTG.exitCount<=0) 
            {

                             //do your thing, save etc
            }   
            MTG.exitCount++;




});
0 голосов
/ 26 ноября 2009

Создайте глобальную переменную со значением true внутри обработчика. Отображать предупреждение / всплывающее окно только в том случае, если эта переменная имеет значение false.

...