Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run Javascript code only if 'beforeunload' function returns true

I'm using JQuery to capture the unload event when a user navigates away from a page. This works just fine, but I have data that needs to be saved only in the event that the user really wants to leave.

Here's my catch-22. If I save the code too early and the user doesn't want to leave, I've spoiled the state of the web service backing the code.

Therefore I need to accomplish the near insurmountable task of executing code only if the 'beforeunload' dialog returns true.

$(window).on('beforeunload', function(e) {
    var info = * some info to save the current page state *
    return 'Are you sure you want to navigate away from the Test Runner?';

    //unreachable place where I wish I could ajax 'info' back to safety
});

This code as is will pop up a dialog that asks 'Are you sure you want to navigate away from the Test Runner?' and if the user clicks cancel will prevent the user from leaving the page.

Here is another thought:

$(window).on('onunload', function(e) {
    var info = * some info to save the current page state *
    var r=confirm('Are you sure you want to stop the Test Runner?');
    if(r==true)
    {
        //place where I wish I could ajax 'info' back to safety
        return 'leaving'
    }
    else
        return 'leaving unsaved';
});

This second method will not prevent the user from leaving either way, but in one case will execute some save code first, and in the other will boot them back out into cold. The issue with this approach is that most browsers (rightfully) prevent confirm boxes from launching in the window.onunload state thanks to years of 90's web developers blindsiding poor dial-up web surfers with it.

A disclaimer: I'm well aware that we in the web developer community strongly discourage preventing the user from leaving a page and executing code in the background as they try to do it. When I see questions like, "How do I prevent a user from leaving my really awesome website" my knee-jerk reaction is typically, "don't do it!" That said this is different. This is a specialized page for a particular client and we need this as a panic-prevention measure. I'm one of the good guys, I promise. I'm one you.

like image 686
darkpbj Avatar asked Apr 03 '13 17:04

darkpbj


3 Answers

Try to use both events. What you need is a shared variable in the same scope, not to say global variable. onbeforeunload will be fired before the dialog appears. onunload will only be fired if the user clicked to escape the window/tab.

// Use a variable in the same scope of both events:
var savedState;

$(window).on('beforeunload', function(e) {

  savedState = "what the user currently made";

  return "Sure U are?";
});

$(window).on('unload', function(e) {

  // user didn't save!!
  // your auto-save function:
  auto_save(savedState);

  // browser leaves this tab.
});

As a scope, I mean something like (function () { })(); or any else (constructor or functional) function.

like image 146
metadings Avatar answered Oct 18 '22 19:10

metadings


Tested and working in chrome.

$(window).on('beforeunload', function () {
   return 'Are you sure you want to navigate away from the Test Runner?';
});
$(window).on('unload', function () {
   $.ajax({ url: '/default.aspx', async: false });
});
like image 24
Brad M Avatar answered Oct 18 '22 20:10

Brad M


Just encountered what your experiencing now

below link is a good reference for this issue.

https://developer.mozilla.org/en-US/docs/Web/Events/unload

"The document is in a particular state:

  • all the resources still exist (img, iframe etc.)
  • nothing is visible anymore to the end user
  • UI interactions are ineffective (window.open, alert, confirm etc.)
  • an error won't stop the unloading workflow"

so you wont be able to fire anything after the beforepageunload since it doesn't yield any return value

like image 28
Marc Avatar answered Oct 18 '22 19:10

Marc