Chrome/Safari not calling unload in some cases - javascript

Have been stuck with this issue for a few days now, and really need, and would appreciate some help. My requirement is that I want to make a server side callback to clear off some objects when the user navigates away from our page, without clicking logout. For business reasons, our ASP.NET session timeout has to be set to a very high value. Further, I do not want to popup a alert/dialog to force the user to return to the page and click Logoff.
The solution I have arrived at thus far is to make a AJAX callback by embedding this javascript in the page.
window.onunload = pageleave;
function pageleave() {
alert('test');
PageMethods.CheckLogout('abc','xyz',OnSucceed,OnFail);
}
Here is the problem though :
For IE and Firefox, the unload fires, the alert is seen, and I see the callback on my C# side in all the cases I desire
a) User closes browser
b) User types in a new URL in the address bar
c) User clicks on a link causing page to reload
For Chrome and Safari, cases a and b work fine. However, when the user clicks on a link, which causes my aspx page to reload, my C# side code is not invoked. The javasacript alert is fired though.
I am trying to see how I can get Chrome/Safari to behave like IE/Firefox. Is this even a possibility?
Thanks in advance for the help,
Rajesh.

Use the beforeunload event instead of the unload event.
Also, use a synchronous AJAX request, not an asynchronous one, so that the request is completed before your beforeunload function exits.
I'm not sure how you would do a synchronous AJAX request using your JavaScript framework. In jQuery, it would look like this:
window.onbeforeunload = function() {
jQuery.ajax({
url: '/page/to/load',
async: false
});
};

In case anyone comes across this in the future, I couldn't use window.onbeforeunload as it was firing too early. Instead, I found window.onpagehide as a suitable workaround.
e.g.
window.onpagehide = function() {
// some code here.
};

Related

How to wait until jquery animation is finished using the onbeforeunload event?

It looks like a basic problem, but I simply can not solve this. I am using an animation to smooth the navigation between pages. The window.onbeforeunload event looks good to fire the animation, but jquery do the animation on a new thread. Is there any way to wait until the animation is finished? I tried using the delay() and setTimeout() jquery functions but they obviously not stopped the function. When I add a loop at the end to wait, the window is not refreshing so the animation not even shown.
My code (jsfiddle):
window.onbeforeunload = function (e) {
$('#loader-sheet').fadeIn(500);
}
From MDN:
When this event returns a non-void value, the user is prompted to confirm the page unload. In most browsers, the return value of the event is displayed in this dialog.
onBeforeUnload is used to prompt a user, not to perform actions (like ajax, animations, or otherwise)
https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload
There's no API to accomplish what you are looking to do. If a user is leaving, the only thing the browser will let you do is prompt them and ask them if they are sure they want to leave. You cannot prevent them (or delay them while still maintaining control of the UI, or anything that uses a JavaScript API) from navigating away from your page.
You cannot prevent the page from changing - you can only present some text as confirmation (e.g. "You have an unsaved draft, are you sure you would like to leave?").
This is by design - imagine if every annoying ad popup was allowed to prevent you from exiting the page by entering a 200-second animation.
However, you might still be able to do something, depending on exactly why the page is changing. For instance, if they are clicking a link on your page (not using back/forward buttons), then you could override the click handler for each of those links, like:
$('a[href]').on('click', function () {
if (/* link would change page */) {
performPageTransition(this.getAttribute('href'));
return false;
}
});
function performPageTransition(newUrl) {
$('#loaderSheet').fadeIn(500, function () {
// Animation complete - move to new URL
window.location = newUrl;
});
}
So instead of following the link instantly, you intercept the click event, and then move the page manually yourself later.
However, I would also consider whether it's possible to load the new page content via AJAX.

IE9 firing onbeforeunload event when the window opens

I'm building a site using the JFileUpload applet and want to handle the closing of a page in a certain way. JSTransferCancelled is called when the applet is cancelled. The following code is what I'm using to handle these events and it works in all browsers except IE.
function JSTransferCancelled(){
bCancel=false;
$.post("cancel.php");
self.close();
}
$(window).load(function(){
$(window).bind('beforeunload',function(){
document.uploader.setEnabled(false);
if(bCancel){ document.uploader.cancel();}
});
});
I open the page with the uploader on it in a new tab from the main site and want to close it when they cancel the upload. When I open the tab in IE, however, I instantly get the alert saying The webpage you are viewing is trying to close this tab. Do you want to close this tab? [OK] [Cancel] and my uploader is both inaccessible because of the setEnabled(false) call and cancelled because of the cancel() call.
What I'm looking for is the same functionality, just in IE. I know there are many many many issues in IE with events like onbeforeunload with it triggering in response to different things, but I've checked for all of those problems in my site and haven't found anything. I haven't run into anything online that deals with the kind of problem I'm having.
I've tried wrapping the onbeforeunload function in different things such as the load function above as well as $(document).ready(), but they either give me the same problems or create new ones.
Check Microsoft's Ridiculous Documentation Then make sure none of the code you are using does anything they list as a trigger to invoke beforeunload, which includes several things that do not actually unload the page (go Microsoft!)

Javascript event that runs before page changes

Is there such a thing?
I know that I can hook my function on the click event of all links, but there are other situations where a page is changed, like refresh or when a different script changes the window.location
In the end, I did it by sending a string trough postMessage from the unload event, like this:
$(window).bind('unload', function(e){
window.parent.postMessage('unloading');
});
in the parent document:
$(window).bind('message', function(e){
if(e.originalEvent.data == 'unloading'){
// ajax stuff here
}
});
It appears to work.
I probably should have mentioned that there's a iframe involved :)
There's the beforeunload event, which is fired when the page is being torn down (either to follow a link, or if the window is being closed, or refresh, etc.). Example:
window.onbeforeunload = function(event) {
var s = "You have unsaved changes. Really leave?";
event = event || window.event;
if (event) {
// This is for IE
event.returnValue = s;
}
// This is for all other browsers
return s;
}
There are, for obvious reasons, very strict limits on what you can do in the handler of the beforeunload event, and as you can see above beforeunload handlers have a different signature than normal event handlers. Basically, your code can't do anything asynchronous, can't open new windows, and can't cancel the event. It can return a string, and if it does, the browser will pop up a window asking whether you really want to leave the page, and including your string in that pop-up.
From your comment on the question:
I need it before so I can fire a ajax request and update some things...
The way to do that here many years after the question was originally asked is with the beacon API. This lets you send a non-blocking asynchronous request to the server without slowing down the process of the browser tearing down your page and navigating to the next:
navigator.sendBeacon("/path/to/notify", optionalData);
It's a send-and-forget, but the browser doesn't cancel it when your page is torn down (like it does a standard asynchronous ajax request). Instead, it allows that request to complete even though your page has been removed.
Back in 2012 when this answer was originally written, you could usually get away with a synchronous ajax call (async: false) provided it didn't take too long. But you can't reliably do that now (and it was never a good idea, it holds up the UI).
jQuery has unload function:
The unload event is sent to the window element when the user navigates
away from the page. This could mean one of many things. The user could
have clicked on a link to leave the page, or typed in a new URL in the
address bar. The forward and back buttons will trigger the event.
Closing the browser window will cause the event to be triggered. Even
a page reload will first create an unload event.
Note that this should be binded to window object instead of document:
$(window).unload(function() {
// do something
});
You can also bind handler to beforeunload event:
$(window).bind('beforeunload', function() {
// do something, preferably ajax request etc
return 'are you sure?';
});
When a page is reloaded, whatever was there before will be gone. Thus, it seems like what you're talking about is something you'd do at DOMReady or "load" in the new page, since you can't "push" code from the former page into the new context.

HTML page unload is not getting called always in IE

I have an onunload method written on the body of a form. Since the page got large amount contents to be streamed from the server,it takes a while to download the entire form. While the form gets downloaded to the browser,if the user clicks the window close button, the unload event (written to call a server side action to reset some flag) is not getting triggered sometimes. The unload method is written towards the end of the page, is that a reason for this? Is there anyway by which we can make sure that onunload is guaranteed to be called?
The thing that hits you is probably the fact that IE doesn't fire an unload event if window.onload hasn't fired yet. The solution is described in this blog post: http://blog.moxiecode.com/2008/04/08/unload-event-never-fires-in-ie/
There are two reasons. One, like you said, the browser may not even be reaching the unload, so you should declare it above your body tag.
The other is that, as GoldenNewby already stated, you need to give the code some time to finish, such as an alert. This is because the JavaScript is cleared from memory the moment the next page is ready, and execution is simply stopped on the old script. If you can guarantee the script will take less time than a page load, you won't need an alert, but if it could take more than 2ms or so to execute, you will need to buy some time.
IE has an onbeforeunload event, you can use that instead. Just set a flag so that your onunload can exit early if onbeforeunload already did its thing.
window.onunload = window.onbeforeunload = function () {
if (window.isAlreadyUnloaded) return;
window.isAlreadyUnloaded = true;
// do your stuff here.
}

How do i handle ajax and closing pages

If the user happens to have a delay in connecting to my site, the ajax hasnt timed out and the user decides to close the window. The ajax query will be terminated? Is there a way i can say still processing are you close you want to leave this page? (bonus if it will close once ajax was successful). How do i do this?
I am not sure if this is the same thing (maybe its built into firefox?) but when i closed this page it said
Are you sure you want to navigate away from this page?
You have started writing or editing a post.
Press OK to continue, or Cancel to stay on the current page.
I am positive i seen this other places. How do i make this appear when the user isnt submitting ajax and is in the middle of a post?
You can use the window.onbeforeunload event to handle this. Set a variable to false at the start of the ajax request. And in the callback function set its value to true, and in the window.onbeforeunload event check that variable and display suitable message.
Note
This will fire when you refresh your page also.
You can implement the onbeforeunload handler in js:
window.onbeforeunload = function()
{
if (showMessage)
{
return trye
}
else
{
return;
}
}

Categories