Rawling
Rawling

Reputation: 50104

setTimeout(x, 0) not delaying in Chrome

I have a web page with a form on it; I want to warn the user if they move away. I haven't implemented dirty checking so my onbeforeunload code is simply

window.onbeforeunload = function () {
    return 'message'
};

I don't want this warning when they submit the form, so I remove the event on submit. However, the submit may fail, so I need to put the event back afterwards (so if they then navigate away they still get warned). To that end I have done the following:

var tempDisableBeforeUnload = function() {
    var obu = window.onbeforeunload;
    if (obu) {
        window.onbeforeunload = null;
        setTimeout(function() {
            window.onbeforeunload = obu;
        }, 0);
    }
}
$("form.noWarnOnSubmit").submit(tempDisableBeforeUnload);

This works fine in Firefox and IE - the setTimeout(x, 0) defers the restoration of the event handler until after the submit has decided whether it is successful or not.

However, in Chrome, the timeout appears to occur immediately, and I get the warning when I submit my form.

How can I make this work on Chrome, or how else can I achieve the end of "don't warn on submit, but put the warning back if the submit fails"?

Upvotes: 0

Views: 160

Answers (2)

Rawling
Rawling

Reputation: 50104

I have overcome my immediate issue by

  • Binding my event to fire after the jQuery validation event, by deferring my submit event binding:
$(function() {
    $("form.noWarnOnSubmit").submit(disableBeforeUnloadIfNotCancelled);
});
  • Changing my event handler to only unbind the onbeforeunload event if the submit event is cancelled.
var disableBeforeUnloadIfNotCancelled = function (e) {
    if (!e.isDefaultPrevented()) {
        window.onbeforeunload = null;
    }
}

Upvotes: 0

somethinghere
somethinghere

Reputation: 17330

Cant you do the following:

var unloadActive = true;
window.onbeforeunload = function () {
    if(unloadActive) return 'message'
};
$("form.noWarnOnSubmit").submit(function(event){
    unloadActive = false;
    // do all your checks and things, whatever, and if the checks fail:
    unloadActive = true;
});

Then you don't need to do all that function juggling which might cause issues. I haven't tested this, but this is how I would do it.

Upvotes: 1

Related Questions