IE9 onbeforeunload вызывается дважды, когда window.location изменяется в событии кнопки ... минимальное воспроизведение - PullRequest
4 голосов
/ 02 апреля 2012

Я вбиваюсь в это и просто не могу никуда добраться.

У меня есть кнопка отмены, которая выполняет "window.location = '404.htm';"при нажатии.Обработчик onbeforeunload запускается дважды, но только если пользователь нажимает «Оставаться на этой странице» в первом диалоговом окне.При обычной навигации (обновление страницы, переход на домашнюю страницу) обработчик onbeforeunload срабатывает только один раз.

Мне удалось воспроизвести поведение с минимальным количеством HTML и сценария:

<!DOCTYPE html>
<html>
<head>
    <title>Test page</title>
</head>
<body onbeforeunload="return 'Unsaved changes';">
    <form name="form1" id="form1">
        <input id='cmdCancel' type="button" value="Cancel" onclick="window.location = '404.htm';" />
    </form>
    <script type="text/javascript">
        /*
         * Connecting the events via code makes no difference
         *
        document.forms[0].cmdCancel.onclick =
            function () {
                alert('Clicked cancel. About to navigate...');
                window.location = '404.htm';
            };

        window.onbeforeunload = function () {
            return "Unsaved changes";
        }; 

        */   
    </script>
</body>
</html>

Есть много хитов для "onbeforeunload, который вызывается дважды", но нет минимального воспроизведения и реальных решений.

Есть предложения?

Спасибо!

Ответы [ 5 ]

4 голосов
/ 11 октября 2012

Попробуй это, у меня это сработало. Это решение было первоначально размещено Амитом на http://social.msdn.microsoft.com/Forums/eu/sharepointinfopath/thread/13000cd8-5c50-4260-a0d2-bc404764966d?prof=required

Помните, ключом является временное отключение onbeforeunload и его повторное включение через некоторое время.

var checkChangesEnabled = true;

window.onbeforeunload = confirmExit;

function confirmExit()
{
  if(checkChangesEnabled)
  {
    event.returnValue = "You have not saved your document yet.";
    disableCheck();
  }
}

function disableCheck()
{
  checkChangesEnabled = false;
  setTimeout("enableCheck()", "100");
}

function enableCheck()
{
   checkChangesEnabled = true;
}
0 голосов
/ 21 января 2017

Я обнаружил, что он вызывается дважды при использовании обратных элементов управления и тегов без тегов asp.Измените элементы управления с <button> на <asp:Button> и т. Д., Чтобы решить эту проблему.

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

С помощью следующего кода вы можете исправить это в любом случае:

window.location = 'javascript:window.location = "http://www.google.com"';
0 голосов
/ 13 сентября 2013

Я думаю, что нашел более чистое решение проблемы.Я установил для onbeforeunload значение null в обратном вызове и сбросил его до выхода:

...
window.onbeforeunload=confirmExit;

function confirmExit(){
    window.onbeforeunload=null;
    event.returnValue="You have not saved your document yet.";
    window.onbeforeunload=confirmExit;
}
0 голосов
/ 02 апреля 2012

Так как в любом случае ваш onbeforeunload интерпретируется через JS, вы, вероятно, можете использовать логический флаг в глобальной переменной, чтобы узнать, запускается ли процесс, запущенный событием впервые.Например:

<head>
  ...
  <script ...>
  var flag=true;
  var ret="";
  function getoff() {
    if(flag) {
      //do your things and save your return value to the global variable "ret"
      //ret="Unsaved changes";
      flag=false; //with this, the code above will be executed only once
    }
    return ret; //the second call will return the same thing as the first call, as first call's return value is stored in a global variable, and is not modified during the second call
  }
  </script>
</head>
<body onbeforeunload="return getoff();">
...

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

<a href="404.htm" id="myButton" style="display:none;visibility:hidden;"></a>

Тогда ваша кнопка может сделать:

<input type="button" ... onclick="document.getElementById('myButton').click();">

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

...