окно.onbeforeunload-показывать предупреждение только при не отправке формы [дубликат]

этот вопрос уже есть ответ здесь:

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

Как я могу это сделать, не показывая предупреждение при отправке формы?

текущий код:

var formHasChanged = false;

$(document).on('change', 'form.confirm-navigation-form input, form.confirm-navigation-form select, form.confirm-navigation-form textarea', function (e) {
    formHasChanged = true;
});

$(document).ready(function () {
    window.onbeforeunload = function (e) {
        if (formHasChanged) {
            var message = "You have not saved your changes.", e = e || window.event;
            if (e) {
                e.returnValue = message;
            }
            return message;
        }
    }
});

4 ответов


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

 var formHasChanged = false;
 var submitted = false;

$(document).on('change', 'form.confirm-navigation-form input, form.confirm-navigation-form select, form.confirm-navigation-form textarea', function (e) {
    formHasChanged = true;
});

$(document).ready(function () {
    window.onbeforeunload = function (e) {
        if (formHasChanged && !submitted) {
            var message = "You have not saved your changes.", e = e || window.event;
            if (e) {
                e.returnValue = message;
            }
            return message;
        }
    }
 $("form").submit(function() {
     submitted = true;
     });
});

вы могли бы использовать .on () для привязки onbeforeunload, а затем использовать .off (), чтобы развязать его в форме представления

$(document).ready(function () {
    // Warning
    $(window).on('beforeunload', function(){
        return "Any changes will be lost";
    });

    // Form Submit
    $(document).on("submit", "form", function(event){
        // disable warning
        $(window).off('beforeunload');
    });
}

вы можете справиться с submit () событие, которое будет происходить только для отправки формы.

в этом событии установите переменную флага formHasChanged в false, чтобы разрешить выгрузку. Кроме того, просто предложение, но поскольку цель этой переменной флага будет изменена, поэтому вы можете переименовать ее что-то вроде "warnBeforeUnload"

$(document).submit(function(){
    warnBeforeUnload = false;
});

я искал лучшее решение для этого. То, что мы хотим, это просто исключить один или несколько триггеров из создания нашего "вы уверены?" диалоговое окно. Поэтому мы не должны создавать все больше обходных путей для все большего количества побочных эффектов. Что делать, если форма представляется без click событие кнопки отправки? Что делать, если наш click-handler удаляет isDirty статус, но затем форма-отправить в противном случае блокируется впоследствии? Конечно, мы можем изменить поведение наших триггеров, но в правильном месте будет логика обработки диалога. Привязка к форме submit событие вместо привязки к кнопке отправки click событие-это преимущество ответов в этом потоке над некоторыми другими, которые я видел раньше, но этот ИМХО просто исправляет неправильный подход.

после некоторого рытья в объекте событие onbeforeunload событие я нашел .target.activeElement свойство, которое содержит элемент, который инициировал событие изначально. Итак, yay, это кнопка или ссылка или то, что мы нажали (или ничего вообще, если браузер сам ушел). Наши "Вы уверены?"логика диалога затем сводится к следующим двум компонентам:

  1. на isDirty обработка формы:

    $('form.pleaseSave').on('change', function() {
      $(this).addClass('isDirty');
    });
    
  2. "вы уверены?"dialog logic:

    $(window).on('beforeunload', function(event) {
      // if form is dirty and trigger doesn't have a ignorePleaseSave class
      if ($('form.pleaseSave').hasClass('isDirty')
          && !$(event.target.activeElement).hasClass('ignorePleaseSave')) {
        return "Are you sure?"
      }
      // special hint: returning nothing doesn't summon a dialog box
    });
    

это просто как это. Обходных путей не требуется. Просто дайте триггеры (отправить и другие кнопки действий)ignorePleaseSave класс и форма, которую мы хотим получить диалог применяется к pleaseSave класса. Все остальные причины для разгрузки страницы затем вызывают наше " Вы уверены?" диалог.

P. S. Я с помощью jQuery, но я думаю, что .target.activeElement свойство также доступно в обычном JavaScript.