问题
I am using window.onbeforeunload to prevent the user from navigating away after changing values on a form. This is working fine, except it also shows the warning when the user submits the form (not desired).
How can I do this without showing the warning when the form submits?
Current code:
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;
}
}
});
回答1:
Using the form's submit event to set a flag might work for you.
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;
});
});
回答2:
you could use .on() to bind onbeforeunload and then use .off() to unbind it in form submission
$(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');
});
}
回答3:
You can handle the submit() event, which will occur only for your form submission.
Within that event, set your flag variable formHasChanged
to false to allow the unload to proceed. Also, just a suggestion, but since the purpose of that flag variable will have changed, so you may want to rename it something like 'warnBeforeUnload'
$(document).submit(function(){
warnBeforeUnload = false;
});
回答4:
I was looking for a better solution to this. What we want is simply exclude one or more triggers from creating our "Are you sure?" dialog box. So we shouldn't create more and more workarounds for more and more side effects. What if the form is submitted without a click
event of the submit button? What if our click-handler removes the isDirty
status but then the form-submit is otherwise blocked afterwards? Sure we can change the behaviour of our triggers, but the right place would be the logic handling the dialog. Binding to the form's submit
event instead of binding to the submit button's click
event is an advantage of the answers in this thread above some others i saw before, but this IMHO just fixes the wrong approach.
After some digging in the event object of the onbeforeunload
event I found the .target.activeElement
property, which holds the element, which triggered the event originally. So, yay, it is the button or link or whatever we clicked (or nothing at all, if the browser itself navigated away). Our "Are you sure?" dialog logic then reduces itself to the following two components:
The
isDirty
handling of the form:$('form.pleaseSave').on('change', function() { $(this).addClass('isDirty'); });
The "Are you sure?" 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 });
It's simply as that. No workarounds needed. Just give the triggers (submit and other action buttons) an ignorePleaseSave
class and the form we want to get the dialog applied to a pleaseSave
class. All other reasons for unloading the page then summons our "Are you sure?" dialog.
P.S. I am using jQuery here, but I think the .target.activeElement
property is also available in plain JavaScript.
来源:https://stackoverflow.com/questions/11766658/window-onbeforeunload-only-show-warning-when-not-submitting-form