I am using web socket connection for communication. But when user refresh page, I want to close this web socket connection.
I also using window.onbeforeunload event to show confirmation box to user with customized text. If user selects 'do not reload' option then no action (which is working fine)
But I want to close web socket connection if user selects reload option. I don't know how to achieve this. I tried to call window.unload and tried to close web socket connection but its not working. My code is as follows.
window.onbeforeunload = function(e) {
return "you are closing this web page';
};
window.unload = function(e) {
webSockect.closeConnection();
};
Please advise how to achieve this.
Window events are prefixed with on.
Try to use window.onunload = ... or even better
window.addEventListener('unload', ...).
When using addEventListener you specify the event name without on prefix.
Read more: WindowEventHandlers.onunload
First of all, there is a syntax error in the code above, you have written:
window.onbeforeunload = function(e) {
return "you are closing this web page';
};
So, type of quotes there should be either single or double, same at start and end of the string.
It is supposed to be, and it will work:
window.onbeforeunload = function(e) {
return "you are closing this web page";
};
====
Back to the point. All you can do with unload prompt is to change the Message. Anything otherwise doesn't work like:
Changing the action on Buttons on the prompt
Changing the Button text of the prompt
Changing the UI of the box
Q. even you write something before the return if the function, that will be ignored by the browser.
You can in fact run a method on close if you assign the method to a variable and then return the variable.
function unloadWebSocket()
{
webSockect.closeConnection();
}
window.onbeforeunload = function(e)
{
var x = unloadWebSocket();
return x;
};
While I have no experience with websockets, I know this works with synchronous ajax requests.
Related
We recently discovered that Chrome no longer supports window.showModalDialog which is problematic because our enterprise application uses this method.
There is, apparently, a short term workaround that allows you to restore showModalDialog but it involves modifying the registry which is too complicated (and risky) four our average user. Therefore I'm not a big fan of this workaround.
The long term solution is obviously to remove all calls to this obsolete method and replace them with a convenient jQuery plugin (such as VistaPrint's Skinny Modal Dialog plugin, for example. Other suggestions are welcome by the way).
The typical scenario we use the modal dialog is to ask the user for Yes/No confirmation before executing an action that cannot be undone, ask the user to agree to terms and condition before proceeding, etc. Typically the onclick event on the "Yes" or "Ok" button in the modal dialog looks like this:
window.returnValue = true;
window.close();
Similarly, the "Cancel" or "No" button looks like this:
window.returnValue = false;
window.close();
The fact that we can return a value from the dialog is very convenient because it allows the "parent" window to be notified whether the user has clicked the "Ok" or the "Cancel" button like so:
var options = "center:1;status:1;menubar:0;toolbar:0;dialogWidth:875px;dialogHeight:650px";
var termsOfServiceAccepted = window.showModalDialog(myUrl, null, options);
if (termsOfServiceAccepted) {
... proceed ...
}
The last thing I'm going to mention about the showModalDialog is that it works great even when the document displayed in the dialog is from a different domain. It's very common for us to have our javascript running from http://the-client.com but the "Terms of Service" web page is from http://the-enterprise-vendor.com
I need a temporary solution that I can deploy ASAP while we work on the long term solution. Here are my criteria:
minimal code change in existing JavaScript
the pop up window must be able to return a value to the "parent". Typically this value is a Boolean but it could be any simple type (e.g.: string, int, etc.)
solution must work even if the URL of the content is from different domain
Here's what I have so far:
1) Add the following method in my JavaScript:
function OpenDialog(url, width, height, callback)
{
var win = window.open(url, "MyDialog", width, height, "menubar=0,toolbar=0");
var timer = setInterval(function ()
{
if (win.closed)
{
clearInterval(timer);
var returnValue = win.returnValue;
callback(returnValue);
}
}, 500);
}
As you can see in this method, I try to make the pop up window look as similar to a dialog as possible by hiding the menu and the toolbar, I setup a time every 500 milliseconds to check if the window has been closed by the user and if so, get the 'returnValue' and invoke a callback.
2) replace all calls to showModalDialog with the following:
OpenDialog(myUrl, 875, 650, function (termsOfServiceAccepted)
{
if (termsOfServiceAccepted)
{
... proceed ....
}
});
The fourth parameter to the method is the callback where I check if the user has clicked the "Ok" button before allowing her to proceed.
I know it's a long question but basically it boils down to:
What do you think of the solution I propose?
In particular, do you think I'll be able to get a returnValue from a window that was opened with window.open?
Any other alternative you can suggest?
I have two ideas that could help you but the first one is tied to CORS, so you won't be able to use it from different domains at least you can access both services and configure them.
FIRST IDEA:
The first one is related to this native api. You could create on the parent window a global function like this:
window.callback = function (result) {
//Code
}
As you can see it receives a result argument which can hold the boolean value you need. The you could open the popup using the same old window.open(url) function. The popup's onlick event handler could look like this:
function() {
//Do whatever you want.
window.opener.callback(true); //or false
}
SECOND IDEA: Solves the problem
The other idea I got is to use this other native api to trigger an event on the parent window when the popup resolves (better known as cross-document messaging). So you could do this from the parent window:
window.onmessage = function (e) {
if (e.data) {
//Code for true
} else {
//Code for false
}
};
By this way you are listening to any posted message on this window, and checking if the data attached to the message is true (the user clicks ok in the popup) or false (the user clicks cancel in the popup).
In the popup you should post a message to the parent window attaching a true or a false value when corresponds:
window.opener.postMessage(true, '*'); //or false
I think that this solution perfectly fits your needs.
EDIT
I have wrote that the second solution was also tied to CORS but digging deeper
I realized that cross-document messaging isn't tied to CORS
We recently discovered that Chrome no longer supports window.showModalDialog which is problematic because our enterprise application uses this method.
There is, apparently, a short term workaround that allows you to restore showModalDialog but it involves modifying the registry which is too complicated (and risky) four our average user. Therefore I'm not a big fan of this workaround.
The long term solution is obviously to remove all calls to this obsolete method and replace them with a convenient jQuery plugin (such as VistaPrint's Skinny Modal Dialog plugin, for example. Other suggestions are welcome by the way).
The typical scenario we use the modal dialog is to ask the user for Yes/No confirmation before executing an action that cannot be undone, ask the user to agree to terms and condition before proceeding, etc. Typically the onclick event on the "Yes" or "Ok" button in the modal dialog looks like this:
window.returnValue = true;
window.close();
Similarly, the "Cancel" or "No" button looks like this:
window.returnValue = false;
window.close();
The fact that we can return a value from the dialog is very convenient because it allows the "parent" window to be notified whether the user has clicked the "Ok" or the "Cancel" button like so:
var options = "center:1;status:1;menubar:0;toolbar:0;dialogWidth:875px;dialogHeight:650px";
var termsOfServiceAccepted = window.showModalDialog(myUrl, null, options);
if (termsOfServiceAccepted) {
... proceed ...
}
The last thing I'm going to mention about the showModalDialog is that it works great even when the document displayed in the dialog is from a different domain. It's very common for us to have our javascript running from http://the-client.com but the "Terms of Service" web page is from http://the-enterprise-vendor.com
I need a temporary solution that I can deploy ASAP while we work on the long term solution. Here are my criteria:
minimal code change in existing JavaScript
the pop up window must be able to return a value to the "parent". Typically this value is a Boolean but it could be any simple type (e.g.: string, int, etc.)
solution must work even if the URL of the content is from different domain
Here's what I have so far:
1) Add the following method in my JavaScript:
function OpenDialog(url, width, height, callback)
{
var win = window.open(url, "MyDialog", width, height, "menubar=0,toolbar=0");
var timer = setInterval(function ()
{
if (win.closed)
{
clearInterval(timer);
var returnValue = win.returnValue;
callback(returnValue);
}
}, 500);
}
As you can see in this method, I try to make the pop up window look as similar to a dialog as possible by hiding the menu and the toolbar, I setup a time every 500 milliseconds to check if the window has been closed by the user and if so, get the 'returnValue' and invoke a callback.
2) replace all calls to showModalDialog with the following:
OpenDialog(myUrl, 875, 650, function (termsOfServiceAccepted)
{
if (termsOfServiceAccepted)
{
... proceed ....
}
});
The fourth parameter to the method is the callback where I check if the user has clicked the "Ok" button before allowing her to proceed.
I know it's a long question but basically it boils down to:
What do you think of the solution I propose?
In particular, do you think I'll be able to get a returnValue from a window that was opened with window.open?
Any other alternative you can suggest?
I have two ideas that could help you but the first one is tied to CORS, so you won't be able to use it from different domains at least you can access both services and configure them.
FIRST IDEA:
The first one is related to this native api. You could create on the parent window a global function like this:
window.callback = function (result) {
//Code
}
As you can see it receives a result argument which can hold the boolean value you need. The you could open the popup using the same old window.open(url) function. The popup's onlick event handler could look like this:
function() {
//Do whatever you want.
window.opener.callback(true); //or false
}
SECOND IDEA: Solves the problem
The other idea I got is to use this other native api to trigger an event on the parent window when the popup resolves (better known as cross-document messaging). So you could do this from the parent window:
window.onmessage = function (e) {
if (e.data) {
//Code for true
} else {
//Code for false
}
};
By this way you are listening to any posted message on this window, and checking if the data attached to the message is true (the user clicks ok in the popup) or false (the user clicks cancel in the popup).
In the popup you should post a message to the parent window attaching a true or a false value when corresponds:
window.opener.postMessage(true, '*'); //or false
I think that this solution perfectly fits your needs.
EDIT
I have wrote that the second solution was also tied to CORS but digging deeper
I realized that cross-document messaging isn't tied to CORS
I am trying to use $.post to send form data to a server side script to be saved if the user tries to leave the page without submitting the form. I am using the same function attached to a save button and on setInterval set to every 2 minutes, and it works fine. But when I attach the function to document.onbeforeunload it does not work. In firebug, I see the request is being sent, but it looks like it is being stopped before a status code is returned and the page continues to unload. I am still pretty new to Javascript and Jquery and I am not sure if maybe $.post is one of those functions that might not work on the onbeforeunload event. If that is true, is there another way I can send the data if the user tries to leave the page without saving?
This is the function I am calling from the onbeforeunload event:
function ajaxSubmit(){
var blogtitle = $("#title").val();
var publishedstate = 0;
var blogid = $("#blogID").val();
var blogbody = CKEDITOR.instances['body'].getData();
var postdata = {ajaxSubmit:true,title:blogtitle,body:blogbody,published:publishedstate,blog_id:blogid};
$.post('ajaxblog.php',postdata,function(data){
$("#autosaveMessage").html(data);
$("#autosaveMessage").show();
setTimeout(function(){$("#autosaveMessage").hide();},5000);
});
}
and this is how I am calling the function:
var post_clicked = false;
$("#postButton").click(function(){
post_clicked = true;
});
function leaveEditor(){
if(post_clicked==false){
ajaxSubmit();
}
else{
//Do Nothing
}
}
window.onbeforeunload = leaveEditor;
No, and this is by design. It would be remarkably troublesome if a page could use onbeforeunload to indefinitely delay browsing away, persist its presence somehow, etc. One of the most important abilities for a user of a web browser to have is the ability to leave.
Just use the stringy return value—the whole point of it is to remind the user that s/he made changes that will be lost. Like on SO :)
How to prevent a webpage from navigating away using JavaScript?
Using onunload allows you to display messages, but will not interrupt the navigation (because it is too late). However, using onbeforeunload will interrupt navigation:
window.onbeforeunload = function() {
return "";
}
Note: An empty string is returned because newer browsers provide a message such as "Any unsaved changes will be lost" that cannot be overridden.
In older browsers you could specify the message to display in the prompt:
window.onbeforeunload = function() {
return "Are you sure you want to navigate away?";
}
Unlike other methods presented here, this bit of code will not cause the browser to display a warning asking the user if he wants to leave; instead, it exploits the evented nature of the DOM to redirect back to the current page (and thus cancel navigation) before the browser has a chance to unload it from memory.
Since it works by short-circuiting navigation directly, it cannot be used to prevent the page from being closed; however, it can be used to disable frame-busting.
(function () {
var location = window.document.location;
var preventNavigation = function () {
var originalHashValue = location.hash;
window.setTimeout(function () {
location.hash = 'preventNavigation' + ~~ (9999 * Math.random());
location.hash = originalHashValue;
}, 0);
};
window.addEventListener('beforeunload', preventNavigation, false);
window.addEventListener('unload', preventNavigation, false);
})();
Disclaimer: You should never do this. If a page has frame-busting code on it, please respect the wishes of the author.
The equivalent in a more modern and browser compatible way, using modern addEventListener APIs.
window.addEventListener('beforeunload', (event) => {
// Cancel the event as stated by the standard.
event.preventDefault();
// Chrome requires returnValue to be set.
event.returnValue = '';
});
Source: https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload
I ended up with this slightly different version:
var dirty = false;
window.onbeforeunload = function() {
return dirty ? "If you leave this page you will lose your unsaved changes." : null;
}
Elsewhere I set the dirty flag to true when the form gets dirtied (or I otherwise want to prevent navigating away). This allows me to easily control whether or not the user gets the Confirm Navigation prompt.
With the text in the selected answer you see redundant prompts:
In Ayman's example by returning false you prevent the browser window/tab from closing.
window.onunload = function () {
alert('You are trying to leave.');
return false;
}
The equivalent to the accepted answer in jQuery 1.11:
$(window).on("beforeunload", function () {
return "Please don't leave me!";
});
JSFiddle example
altCognito's answer used the unload event, which happens too late for JavaScript to abort the navigation.
That suggested error message may duplicate the error message the browser already displays. In chrome, the 2 similar error messages are displayed one after another in the same window.
In chrome, the text displayed after the custom message is: "Are you sure you want to leave this page?". In firefox, it does not display our custom error message at all (but still displays the dialog).
A more appropriate error message might be:
window.onbeforeunload = function() {
return "If you leave this page, you will lose any unsaved changes.";
}
Or stackoverflow style: "You have started writing or editing a post."
If you are catching a browser back/forward button and don't want to navigate away, you can use:
window.addEventListener('popstate', function() {
if (window.location.origin !== 'http://example.com') {
// Do something if not your domain
} else if (window.location.href === 'http://example.com/sign-in/step-1') {
window.history.go(2); // Skip the already-signed-in pages if the forward button was clicked
} else if (window.location.href === 'http://example.com/sign-in/step-2') {
window.history.go(-2); // Skip the already-signed-in pages if the back button was clicked
} else {
// Let it do its thing
}
});
Otherwise, you can use the beforeunload event, but the message may or may not work cross-browser, and requires returning something that forces a built-in prompt.
Use onunload.
For jQuery, I think this works like so:
$(window).unload(function() {
alert("Unloading");
return falseIfYouWantToButBeCareful();
});
If you need to toggle the state back to no notification on exit, use the following line:
window.onbeforeunload = null;
I need to warn users about unsaved changes before they leave a page (a pretty common problem).
window.onbeforeunload = handler
This works but it raises a default dialog with an irritating standard message that wraps my own text. I need to either completely replace the standard message, so my text is clear, or (even better) replace the entire dialog with a modal dialog using jQuery.
So far I have failed and I haven't found anyone else who seems to have an answer. Is it even possible?
Javascript in my page:
<script type="text/javascript">
window.onbeforeunload = closeIt;
</script>
The closeIt() function:
function closeIt()
{
if (changes == "true" || files == "true")
{
return "Here you can append a custom message to the default dialog.";
}
}
Using jQuery and jqModal I have tried this kind of thing (using a custom confirm dialog):
$(window).beforeunload(function () {
confirm('new message: ' + this.href + ' !', this.href);
return false;
});
which also doesn't work - I cannot seem to bind to the beforeunload event.
You can't modify the default dialogue for onbeforeunload, so your best bet may be to work with it.
window.onbeforeunload = function() {
return 'You have unsaved changes!';
}
Here's a reference to this from Microsoft:
When a string is assigned to the returnValue property of window.event, a dialog box appears that gives users the option to stay on the current page and retain the string that was assigned to it. The default statement that appears in the dialog box, "Are you sure you want to navigate away from this page? ... Press OK to continue, or Cancel to stay on the current page.", cannot be removed or altered.
The problem seems to be:
When onbeforeunload is called, it will take the return value of the handler as window.event.returnValue.
It will then parse the return value as a string (unless it is null).
Since false is parsed as a string, the dialogue box will fire, which will then pass an appropriate true/false.
The result is, there doesn't seem to be a way of assigning false to onbeforeunload to prevent it from the default dialogue.
Additional notes on jQuery:
Setting the event in jQuery may be problematic, as that allows other onbeforeunload events to occur as well. If you wish only for your unload event to occur I'd stick to plain ol' JavaScript for it.
jQuery doesn't have a shortcut for onbeforeunload so you'd have to use the generic bind syntax.
$(window).bind('beforeunload', function() {} );
Edit 09/04/2018: custom messages in onbeforeunload dialogs are deprecated since chrome-51 (cf: release note)
What worked for me, using jQuery and tested in IE8, Chrome and Firefox, is:
$(window).bind("beforeunload",function(event) {
if(hasChanged) return "You have unsaved changes";
});
It is important not to return anything if no prompt is required as there are differences between IE and other browser behaviours here.
While there isn't anything you can do about the box in some circumstances, you can intercept someone clicking on a link. For me, this was worth the effort for most scenarios and as a fallback, I've left the unload event.
I've used Boxy instead of the standard jQuery Dialog, it is available here: http://onehackoranother.com/projects/jquery/boxy/
$(':input').change(function() {
if(!is_dirty){
// When the user changes a field on this page, set our is_dirty flag.
is_dirty = true;
}
});
$('a').mousedown(function(e) {
if(is_dirty) {
// if the user navigates away from this page via an anchor link,
// popup a new boxy confirmation.
answer = Boxy.confirm("You have made some changes which you might want to save.");
}
});
window.onbeforeunload = function() {
if((is_dirty)&&(!answer)){
// call this if the box wasn't shown.
return 'You have made some changes which you might want to save.';
}
};
You could attach to another event, and filter more on what kind of anchor was clicked, but this works for me and what I want to do and serves as an example for others to use or improve. Thought I would share this for those wanting this solution.
I have cut out code, so this may not work as is.
1) Use onbeforeunload, not onunload.
2) The important thing is to avoid executing a return statement. I don't mean, by this, to avoid returning from your handler. You return all right, but you do it by ensuring that you reach the end of the function and DO NOT execute a return statement. Under these conditions the built-in standard dialog does not occur.
3) You can, if you use onbeforeunload, run an ajax call in your unbeforeunload handler to tidy up on the server, but it must be a synchronous one, and you have to wait for and handle the reply in your onbeforeunload handler (still respecting condition (2) above). I do this and it works fine. If you do a synchronous ajax call, everything is held up until the response comes back. If you do an asynchronous one, thinking that you don't care about the reply from the server, the page unload continues and your ajax call is aborted by this process - including a remote script if it's running.
This can't be done in chrome now to avoid spamming, refer to javascript onbeforeunload not showing custom message for more details.
Angular 9 approach:
constructor() {
window.addEventListener('beforeunload', (event: BeforeUnloadEvent) => {
if (this.generatedBarcodeIndex) {
event.preventDefault(); // for Firefox
event.returnValue = ''; // for Chrome
return '';
}
return false;
});
}
Browsers support and the removal of the custom message:
Chrome removed support for the custom message in ver 51 min
Opera removed support for the custom message in ver 38 min
Firefox removed support for the custom message in ver 44.0 min
Safari removed support for the custom message in ver 9.1 min
Try placing a return; instead of a message.. this is working most browsers for me.
(This only really prevents dialog's presents)
window.onbeforeunload = function(evt) {
//Your Extra Code
return;
}
You can detect which button (ok or cancel) pressed by user, because the onunload function called only when the user choise leaveing the page. Althoug in this funcion the possibilities is limited, because the DOM is being collapsed. You can run javascript, but the ajax POST doesn't do anything therefore you can't use this methode for automatic logout. But there is a solution for that. The window.open('logout.php') executed in the onunload funcion, so the user will logged out with a new window opening.
function onunload = (){
window.open('logout.php');
}
This code called when user leave the page or close the active window and user logged out by 'logout.php'.
The new window close immediately when logout php consist of code:
window.close();
I faced the same problem, I was ok to get its own dialog box with my message, but the problem I faced was :
1) It was giving message on all navigations I want it only for close click.
2) with my own confirmation message if user selects cancel it still shows the browser's default dialog box.
Following is the solutions code I found, which I wrote on my Master page.
function closeMe(evt) {
if (typeof evt == 'undefined') {
evt = window.event; }
if (evt && evt.clientX >= (window.event.screenX - 150) &&
evt.clientY >= -150 && evt.clientY <= 0) {
return "Do you want to log out of your current session?";
}
}
window.onbeforeunload = closeMe;
<script type="text/javascript">
window.onbeforeunload = function(evt) {
var message = 'Are you sure you want to leave?';
if (typeof evt == 'undefined') {
evt = window.event;
}
if (evt) {
evt.returnValue = message;
}
return message;
}
</script>
refer from http://www.codeprojectdownload.com
What about to use the specialized version of the "bind" command "one". Once the event handler executes the first time, it’s automatically removed as an event handler.
$(window).one("beforeunload", BeforeUnload);
Try this
$(window).bind('beforeunload', function (event) {
setTimeout(function () {
var retVal = confirm("Do you want to continue ?");
if (retVal == true) {
alert("User wants to continue!");
return true;
}
else {
window.stop();
return false;
}
});
return;
});