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: |
Description
Moved from: http://bugs.jqueryui.com/ticket/8439
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.
Scenarios:
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 null
ing 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 comment:1
component: | unfiled → event |
---|---|
milestone: | None → 1.9 |
priority: | undecided → low |
status: | new → open |
Changed July 11, 2012 07:07PM UTC by comment:2
Changed October 21, 2012 02:33AM UTC by comment:3
resolution: | → fixed |
---|---|
status: | open → closed |
Fix #12061. Avoid window.onbeforeunload to permit multiple handlers. Close gh-894.
Changeset: 9dd0b010174dbfa70142a995a875a316337e1913
Changed October 22, 2012 03:12AM UTC by 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 comment:5
As of 1.9.2. release, existing onbeforeunload handler is still getting clobbered.
Changed November 26, 2012 01:42PM UTC by 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 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 comment:9
Don't return null
, return *nothing* so its undefined
.
Changed July 01, 2013 05:48PM UTC by comment:10
Hello
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 http://jsfiddle.net/7A6Ne/
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 http://bugs.jquery.com/ticket/13171