Window.onbeforeunload - know what the user clicked

I am currently developing an Intranet that runs in IE only (no, I am not able to decide what browser they use here).

Before the user leaves the page I check if they changed any form field and didnt submit. I have something like this

window.onbeforeunload = function()
    var bUnsavedFields = FormUtil.checkModifiedFields("formToCheck");

        window.event.returnValue = "You have unsaved work";

Question is now, I want to know what the user pressed. If he pressed [ OK ] then run function a, if he presses [ Cancel ] then run function b. It doesn’t seem to be possible to achieve this…

I’m not sure where the Ok and Cancel originate, but it is possible to capture keyboard or on-page events, not events involving browser chrome.

If you’re popping up a standard browser confirmation box, you can execute different functions depending on the button clicked.

Try this simple test to see if it’s the kind of functionality you’re after:

window.onload = function() {
	if (window.confirm('yes/no?'))

JVLB, try the example (without the boolean value check) and you will see what dialog I am talking about.

Iain, thanks, but that is not really what I asked for. If the user leaves the page without saving, the unbeforeunload checks this. Using a confirm will not help in this case. Since it will only stay on the same page if cancel is pressed. That is ok, but I then want to call a function. This is not possible it seems.

What happens if you use setTimeout() to call a function one second after that event? If the user clicked ok, the page would unload before the time was up, right?

window.onbeforeunload = function()
    var bUnsavedFields = FormUtil.checkModifiedFields("formToCheck");

        window.event.returnValue = "You have unsaved work";

well, the weird this is that ANY JavaScript will actually trigger in this anonymous onbeforeunload function. And it will trigger before the dialog, even though the code is afterwards.

So, it doesn’t seem to be possible to trigger a function only if the user pressed “cancel”.

Take a look at this. (be sure to read the comments)

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title>onbeforeunload test</title>
<script type="text/javascript"><!--
window.onbeforeunload = function() {
  // in Firefox and Netscape 7.2+ the setTimeout or setInterval do not wait
  // to be executed until after the user clicks one of the buttons in the
  // confirm()-like box.

  //setTimeout("alert('hi from setTimeout()');",500);
  // setTimeout() and setInterval() aren't called when ok is clicked in
  // IE5-6/Win, but is called in IE7 when the time is short, but not when
  // it's longer, like 500 (a half second).
  window.unloadTimer = setInterval(
    "alert('hi from setInterval()');clearInterval(window.unloadTimer);",500);
  window.onunload = function() {clearInterval(window.unloadTimer);}
  return 'onbeforeunload testing';
// -->

<h1>onbeforeunload test</h1>


How about triggering the dialog with onbeforeunload then calling your functions with onunload?

JVLB, the dialog is being triggered using the onbeforeunload.

Kravvitz, Horrible hack, but it works :wink: Thank you very much.

That I understood, but I thought the problem was premature code execution in the onbeforeunload handler which could be addressed by placing the code in question in an onunload handler.

Hello all,

Kravvitz, question - I see in your notes that you say

“setTimeout or setInterval do not wait to be executed until after the user clicks one of the buttons in the confirm()-like box.”

Is there any way to get Firefox to wait? I have done something very similar to this, and it works well for me in IE, but I’d love to find a way to get something to happen after I click Cancel on the onbeforeunload’s dialog.

Anyone have a suggestion? Simply not possible? Thanks!

A bit of background before my next question/thought about this…

I need to track when the user leaves the webpage. I am setting a 2 minute timer to go off when the onbeforeunload event is called. After the 2 minutes, the user’s session is invalidated.

What I’m trying to achieve is to cancel the timer if the user clicks “Cancel” on the onbeforeunload event. The earlier code posted does indeed allow this to happen with IE because IE waits for me to answer the OK - Cancel question before firing the alert message.

As the notes from Kravvitz’s code say, and as I’ve found myself, Firefox doesn’t wait, so I can’t go off and cancel the timer quite yet because the user hasn’t made a choice. Waiting for one second also will not likely give the user enough time to answer. I can increase the setTimout to something like 10 or 20 seconds, and then reset the timer, but then I would have to hope that the user actually makes the choice before that time is up.

I would obviously much rather implement it so the timer is only cancelled when the user presses “Cancel”. If there were a way to check to see if the prompt was still open, then I could extend the timer. If the prompt was closed, I would know the user pressed “Cancel”. I don’t know of a way to do this, however.

Any thoughts/additions/suggestions?

Thanks for the help.

Have you tried using onunload instead of onbeforeunload. I don’t know of any other way around this. You could put this in as a Mozilla feature request, if no one else has already.

Yes, I’ve tried the onunload, but get the age-old problem - there isn’t enought time to execute my code before the page exits. (My code checks what page the user was on - a post to a jsp that needs a few extra precious miliseconds).

I can put the setTimeout to be slightly less than my timer that will execute my task, and that will almost take care of the problem. Let’s say I put the setTimeout to be 2 minutes. The remaining issue there would be when the prompt is displayed and the user doesn’t make a choice within that two minutes and then clicks “OK”, the browser will close, but since the two minutes passed, I had cancelled the timer, so I didn’t accurately capture the fact that the user left.

That probably doesn’t make sense by now. Thanks for the suggestions, though, and feel free to give a few more if you think of them.