Skip to main content

Bug Tracker

Side navigation

#12061 closed bug (fixed)

Opened July 11, 2012 06:58PM UTC

Closed October 21, 2012 02:33AM UTC

Last modified July 01, 2013 05:50PM UTC

$(window).beforeunload() clobbers previous handler and return values

Reported by: dmethvin Owned by:
Priority: low Milestone: 1.9
Component: event Version: 1.7.2
Keywords: Cc:
Blocked by: Blocking:

Moved from:

No matter what $(window).beforeunload(fn) does, it cannot interact reliably with a mix of native inline functions. For other events, jQuery attaches a private native handler via addEventListener or attachEvent and manages jQuery handlers in its own data structures. Here we are all trying to share a single window.onbeforeunload property, and it can't work.


   window.onbeforeunload = fn1;
   $(window).on("beforeunload", fn2);
   $(window).on("beforeunload", fn3);

Currently, we clobber fn1 and it is never called; only fn2 and fn3 would be called.

   window.onbeforeunload = fn1;
   $(window).on("beforeunload", fn2);
   $(window).on("beforeunload", fn3);
   window.onbeforeunload = null;

If the code that sets fn1 later tries to remove it by nulling out the handler, fn2 and fn3 don't run.

Having jQuery and the native code save any existing handler allows everyone to run, but prevents anyone from removing their handler; perhaps that is less of a problem in real-life scenarios.

There is also the return value problem. Unlike other event handlers that return false as a flag, the onbeforeunload event returns a **string** that is supposed to be displayed to the user, such as "Are you sure you want to leave this page? Your edits will be lost". In the case that there are multiple handlers what should be displayed to the user? Right now, we display the string from the *last* jQuery handler called.

Attachments (0)
Change History (11)

Changed July 11, 2012 07:00PM UTC by dmethvin comment:1

component: unfiledevent
milestone: None1.9
priority: undecidedlow
status: newopen

Changed July 11, 2012 07:07PM UTC by dmethvin comment:2

Changed October 21, 2012 02:33AM UTC by Oleg comment:3

resolution: → fixed
status: openclosed

Fix #12061. Avoid window.onbeforeunload to permit multiple handlers. Close gh-894.

Changeset: 9dd0b010174dbfa70142a995a875a316337e1913

Changed October 22, 2012 03:12AM UTC by anonymous comment:4

Replying to [comment:3 Oleg]:

Changeset: 9dd0b010174dbfa70142a995a875a316337e1913

This does not appear to be the correct changeset link.

Changed November 26, 2012 08:05AM UTC by skarkkai comment:5

As of 1.9.2. release, existing onbeforeunload handler is still getting clobbered.

Changed November 26, 2012 01:42PM UTC by dmethvin comment:6

skarkkai, the test case above works. If you have a test case that fails can you post it?

Changed November 26, 2012 01:44PM UTC by dmethvin comment:7

Test case that also includes the native onbeforeunload, which also works.

Changed February 08, 2013 06:46PM UTC by comment:8

The string to be showed has to be the last valid string so if the last callback returns null the page doesn't close without confirmation.

Changed February 13, 2013 09:35PM UTC by dmethvin comment:9

Don't return null, return *nothing* so its undefined.

Changed July 01, 2013 05:48PM UTC by comment:10


Recently I needed to make a queue that is updated via ajax.

It is updated recursively with a interval between each request.

Users complained that they were receiving an error message when accessed any link while the queue is updated.

So I needed to identify if the onError was called by a failure or because the user left navigation during the ajax request.

I fulfilled using the combination of $.ajaxError and $.bind('beforeunload', func) in the following code

But I just tested in Chrome 27, IE 10 and Firefox, so I'm afraid because I do not know if implementation of beforeunload is ok in all major browsers.

Should be fine if $.ajaxError tell us if user left navigation.

Changed July 01, 2013 05:50PM UTC by comment:11

Sorry, I posted in the wrong ticket.

It is the correct