views:

51

answers:

1

I want to control how easily people can leave my app. Now, I know I can't do it completely; that's what cron jobs are for. But I'd like to catch as many cases as possible.

I thought, I could use onBeforeUnload to display the dialog box, warning them about leaving and asking them to please click the Quit button instead.

But then I found out that it could be possible to run a synchronous AJAX (heh) call when onBeforeUnload is called; the benefit of it being synchronous is that the browser will wait for it to finish before continuing, as I understand it. That way, I could tell the server that I'm logging off as they close the window. And because it's in onBeforeUnload and not onUnload, all of the data is still extant and the call will be sent.

My question is, is it possible to combine these? I would like a popup warning them about leaving, and then IF they continue to want to leave, send the message that they are in fact leaving.

The way I understand it, I can't do this; I can do:

  1. Send the message only
  2. Put up the dialog only
  3. Send the message and put up the dialog

... but I can't send the message conditionally on if they accepted the dialog, right? My understanding is that when they click "OK, I want to leave", it immediately fires onUnload, and by that point it's too late. And #3 above isn't useful because I don't want to send the message that they're logging off, and then have them cancel the dialog and stay on the page.

Can I have my cake and eat it too? Can I ask them if they want to leave and, if so, send the message?

A: 

As I already stated in a comment, onbeforeunload doesn't function in Opera. However, I tried the following code in Firefox (3.6.3/Linux) and Chromium (5.0.375.70) and it worked more or less. However, when closing the Chromium window or tab, the confirmation box is shown, but within a second the window/tab is closed, even when clicking Ok. There seems to be a timeout for synchronous XMLHttpRequests during onbeforeunload.

window.onbeforeunload = function () {
    if (confirm("Send unsaved data?"))
        sendData();

};

function sendData() {
    var request = new XMLHttpRequest();
    request.open("POST", "wait.php", false); // false = synchronous request
    request.send('data={"foo":"bar"}');
    if (request.readyState == 4 && request.status == 200)
        alert("Succes!");

}

Update – Just for the sake of completeness, as I forgot to include wait.php, it just holds the connection for 10 seconds:

<?php sleep(10); ?>
Marcel Korpel
This will likely only be used in FF and IE anyway, I'm not going out of my way to support Opera and Chrome (it's an in-house app). But that still sounds kind of sketchy. Based on what I'm seeing, I think I'd rather just throw my lot with `cron`. (Again, not that it wasn't going to exist *anyway*, I just wanted to see how graceful I could make closing the app. Not too much, it seems.)
Andrew
@Andrew: Indeed. It's just that the web was not designed to do these kind of things.
Marcel Korpel