Могу ли я предотвратить вызов window.onbeforeunload при выполнении вызова AJAX - PullRequest
22 голосов
/ 11 февраля 2009

У меня есть элемент управления сеткой на основе AJAX.

Мы подключаемся к событию window.onbeforeunload, чтобы проверить, есть ли у них несохраненные данные, и если это так, представим им сообщение «Вы уверены, что хотите уйти ... у вас есть несохраненные данные ...».

Все это хорошо.

Но вызовы AJAX также запускают window.onbeforeunload, и поэтому, если сетка содержит несохраненные данные, и мы делаем вызов AJAX (например, чтобы удалить строку в другой сетке), пользователь получает «Вы уверены, что хотите отказаться от навигации. ... у вас есть несохраненные данные ... "сообщение не очень хорошее.

Можно ли подавить событие onbeforeunload для вызовов AJAX? Или можно обнаружить, что вызов является вызовом AJAX? В противном случае нам придется взломать!

Спасибо

Ответы [ 9 ]

30 голосов
/ 24 марта 2010

Если вы хотите инициировать обратную передачу по гиперссылке, существует простой обходной путь: Вместо

<a href="javascript:submitFunction();">Submit</a>

или

<a href="javascript:;" onclick="submitFunction();">Submit</a>

просто используйте этот код:

<a href="#" onclick="submitFunction();">Submit</a>

Похоже, что IE запускает событие onbeforeunload, если содержимое атрибута href гиперссылки не является текущей страницей (что указывает острый символ).

5 голосов
/ 14 ноября 2009

Я сделал что-то вроде этого:

тег внутри тела:

  var allowConfirm = true;

  window.onbeforeunload = confirmExit;
  function confirmExit()
  {
    if(allowConfirm)
        return "Are you sure you want to navigate away from this page?";
    else
        allowConfirm = true;
  }

Когда я выхожу из системы, я вызываю этот скрипт:

allowConfirm = false; возврат window.location.href;

2 голосов
/ 10 июня 2011

В случае IE6 или href вы можете подключить функцию обратной передачи. то есть: если функция обратной передачи WebForm_DoPostBackWithOptions и использует Jquery, добавьте этот код ниже к коду выше

var DoPostBackWithOptionsHook = null;

$(document).ready(function(){
  DoPostBackWithOptionsHook = WebForm_DoPostBackWithOptions;
  WebForm_DoPostBackWithOptions = WebForm_DoPostBackWithOptionsHook;
}

function WebForm_DoPostBackWithOptionsHook(options) {
    var navigateAwayFlag = $("input[id*='navigateAwayValue']");
       if (navigateAwayFlag.length > 0) {
           navigateAwayFlag[0].value = "false"; }

    return DoPostBackWithOptionsHook(options)
}
2 голосов
/ 11 февраля 2009

Это действительно странно, вы уверены, что ваш Ajax-вызов не загружает новую ссылку?

Обязательно прочитайте соответствующую спецификацию: onbeforeunload spec

Проверьте, может ли вызов Ajax вызвать какое-либо из действий, перечисленных в таблице Для вызова .

0 голосов
/ 21 января 2017

Не использовал AJAX, но все же хотел предотвратить выход страницы с несохраненными изменениями. Я попробовал большинство предыдущих предложений, в том числе navigateAway. Ни один из них не работал с IE 8. NavigateAway всегда возвращал длину 0.

Я нашел блог, в котором было решение об использовании класса в качестве идентификатора в теге, а затем о настройке логического значения на основе этого. Я попробовал это, но это не работает, потому что .NET при выводе HTML оборачивал входной тег в тег span с объявленным в нем классом. Мое окончательное решение состояло в том, чтобы вставить слово Ignore в имя идентификатора тега. Кроме того, чтобы предотвратить вызов onbeforeunload до того, как щелчок перехватывается кодом, который устанавливает логическое значение, необходимо использовать, например, asp: Button или asp: Input. Наконец, asp заставляет (из VS IDE) начальное имя быть типом управления; ID = "Button_Save". Использование тегов asp: также предотвращает двойной вызов onbeforeunload.

<script type="text/javascript" language="javascript">
 var stuffchanged = false
 var ignorenavigate = false

  $(document).ready(function () {


    //Detect whether the event source has "nonavigate" class specified
    $("a,input,img,checkbox,button").click(function () {
        var str = $(this).attr("ID");
        ignorenavigate = str.search("Ignore") > 0;
    });

});

window.onbeforeunload = confirmExit;
function confirmExit() {
    if (stuffchanged && !ignorenavigate) {
        return "You have attempted to leave this page with unsaved changes.  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?";
    }  

}

  function textchanged() {
     stuffchanged = true;
  }

0 голосов
/ 24 июля 2012

это невозможно, нет способа узнать, была ли нажата кнопка обновления браузера.

0 голосов
/ 09 июня 2012

Одним из способов решения этой проблемы является вызов submitFunction () для события click тега гиперссылки с использованием jquery и удаление атрибута href из гиперссылки.

0 голосов
/ 25 марта 2010

Это на самом деле работает:

 OnClientClick="eval(this.href);return false" 
0 голосов
/ 21 июля 2009

Если вы говорите о частичной обратной передаче ASP.NET AJAX, то я столкнулся с этим и сегодня, делая то же самое. (Если нет, полностью игнорируйте мой пост.)

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

Наличие на странице определенного скрытого поля - это уже то, что я использовал для определения на стороне клиента, когда уместно показывать предупреждение об отсутствии навигации, поэтому я смог исправить это очень просто, добавив проверку скрытого значение поля для условия if моего onbeforeunload, и подключение к обработчикам PageRequestManager BeginRequest и EndRequest для установки значения. Это эффективно отключает предупреждение при частичной обратной передаче. Вы могли бы добавить более сложную логику, если бы вы хотели проверить более конкретные вещи.

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

window.onbeforeunload = checkNavigateAway;

Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(onBeginRequest);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onEndRequest);

function onBeginRequest(sender, args) {
    var navigateAwayFlag = $("input[id*='navigateAwayValue']");
    if (navigateAwayFlag.length > 0) {
        navigateAwayFlag[0].value = "false";
    }
}

function onEndRequest(sender, args) {
    var navigateAwayFlag = $("input[id*='navigateAwayValue']");
    if (navigateAwayFlag.length > 0) {
        navigateAwayFlag[0].value = "true";
    }
}

function checkNavigateAway() {
    var navigateAwayFlag = $("input[id*='navigateAwayValue']");
    if (navigateAwayFlag.length > 0 && navigateAwayFlag[0].value == "true")
    {
        return "Warning Text";
    }
}

Редактировать : Плохие новости. Вышеуказанное не работает в IE6. Кажется, что он запускает события в другом порядке, чем Firefox, поэтому onbeforeunload срабатывает до AJAX beginRequest ... Возможно, придется найти способ изменить значение флага через щелчок гиперссылки до того, как сработает onbeforeunload.

...