Tue
25
Nov '08
|
by schlumpf filed under Computer
|
Today I wanted to implement something that would prevent me from accidentally closing the browser window while I was doing stuff in my webapp. I’m no javascript expert, so I checked some newsgroups and found more and more complex solutions the longer the threads were.
Here’s what works for me:
<script type="text/javascript"> window.onbeforeunload = function(){ return "Did you save your stuff?" } </script>
I have no idea why this behaves as it does, it must be one of those “very interesting ideas” Frank mentioned about javascript.
What it does is this: When the user presses the browser’s “x” to close the window, this dialog box is shown:
If the user presses Cancel, the box disappears and the browser window remains open, and if she presses Okay, the browser window closes (who’d have guessed). So far, so good. Unfortunately the message is displayed even if the user clicks on a link or submits a form (to do something within the webapp) .
So how do I fix this? The newsgroups said that I could add a condition to check if I really want to warn the user about closing, like this:
<script type="text/javascript"> var hook=true; window.onbeforeunload = function() { if (hook) { return "Did you save your stuff?" } // no return value obviously means no dialog box. } function unhook() { hook=false; } </script>
The default is to use the hook, and I can use the unhook()
function to disable the hook. How does this help? How do I know when I want the hook disabled? Frank knew the solution, and it’s really very simple: I want to disable the hook whenever the user clicks on one of my own links or buttons within the webapp. This can be done by adding an onClick
event to each link or button like this:
<a href="..." onClick="unhook()">Some link within my app</a>
At first it looks a bit cumbersome to change all the links and buttons, but in a webapp, most of the links will be written by some application code anyway so it’s not much trouble to change them all at once.
It’s a bit strange because what I’m doing here is programming some general behaviour (the hook) and then exclude all the common use-cases (internal links, by calling unhook()) because I can’t make javascript react to the few exceptions (browser close button) directly.
The final page looks something like this:
<html> <head> <script type="text/javascript"> var hook = true; window.onbeforeunload = function() { if (hook) { return "Did you save your stuff?" } } function unhook() { hook=false; } </script> </head> <body> <!-- this will ask for confirmation: --> <a href="http://google.com">external link</a> <!-- this will go without asking: --> <a href="anotherPage.html" onClick="unhook()">internal link, un-hooked</a> </body> </html>
Closing or re-loading the window will display the confirm box, too.
Use the following links to check that it works:
Don’t leave for Google before you leave a comment.
You shouldn’t be able to close this page without warning, either.
There’s one small problem left: if you click on the “leave a comment” link, the page will not be re-loaded because it’s just a page-internal link, and after that, the hook variable will be false and you won’t be asked for confirmation if you click on the google link again. But thankfully I don’t have these page-internal links in my webapp…
Addendum: Claus Augusti directed my attention to two official documentation sites about the onbeforeunload event. Thanks you! The documentation in the Mozilla Developer Center explains that one should not just return a string, but should assign a value to the returnValue property of the onbeforeunload event (browser-dependent), like this:
window.onbeforeunload = function (e) { var e = e || window.event; if (e) { // For IE and Firefox e.returnValue = 'Any string'; } return 'Any string'; // For Safari };
This is contradictory to the example given in Microsoft’s documentation (returning a string is sufficient), and contrary to my experience with Firefox, but at least it helps to understand why this works at all.
Can we customize the message displayed on the popup box?
I just want to display my required message without the inbuilt ones (Are you sure you want to navigate away from this page? Press OK to continue or Cancel to stay on the current page).
Hi Suhail,
thanks for your comment! It is not possible to remove or change the inbuilt message. See also the documentation on msdn.microsoft.com (section “Remarks”).
Suhail
I using similar code to display a message box when the user navigates away from the page without saving it.
But I get javascript error : “unspecified error” when cancel button is clicked in the message box.
Below is my code,
var needToConfirm = true;
window.onbeforeunload = confirmExit;
function confirmExit()
{
if(needToConfirm)
return ‘You have made changes to the fields. Without clicking the Save button, your changes will be lost.’;
}
Thanks in advance, VJ.
Schlumpf
The last post is for you, I’ve addressed it wrongly.
Any help on that is much appreciated.
Thanks, VJ
Hi VJ,
thanks for your comment! Your code works fine in my browser (Firefox 3.0.8 on Gentoo Linux). What browser are you using?
One thing you might want to try is use the event.returnValue as described in the addendum to the original post. Or you could install FireBug, the javascript debugging plugin for Firefox, and try to find out what’s going on (if you are using Firefox at all). Hope this helps!
Hello,
I appreciate the way you have opted for displaying warning message. But I am not satisfied with this code as it does not function properly. Browser close message should only be called when someone closes or refreshes not by clicking links. Links where you have mentioned onClick=”unhook()” works fine but after clicking such a link if you close or refresh the browser the Warning message does not appear, have you really tested it? If not then check this scenario…I would really thank you if you can resolve this issue. Even I had written the same, here it is:
// warning message javascript
var needToConfirm = true;
window.onbeforeunload = confirmExit;
function confirmExit()
{
if (needToConfirm)
return “”;
}
and then for links: Test
But once you click the link the state remains in FALSE and that’s why the Warning message does not show. Let me know if you could fix this?
Cheers,
Ayush
Hi Ayusman,
thanks for your comment! I’m not sure if wordpress didn’t scramble the test link in your comment – it was just empty <a>Test</a>. If this is what you intended, then I think I know why the unhook-Thing doesn’t work properly in your case. Normally, when you click a link, the browser reloads the page, which automatically resets all javascript variables. In your case, no reload is triggered and all variables remain unchanged – the needToConfirm variable will still be false.
Hey,
Thanks for your reply on this. What I wanted to tell you is: in an anchor tag to avoid the onClick function triggering the prompt box you are setting the onClick as false, right. So what’s happening once you click this link and then when you try refreshing or closing the browser the Warning Message will not appear because the onClick is set as false…
Hope you got me now else I will again explain you…
Did you get to understand the scenario which I had been trying to explain you?
Okay, looks like you are confused…See for example I have a website which uses JSF and links are defined in h:commandlink tag. Now if I want to make 1000 links as onclick my warning message function as false then I would not prefer to go to each link and add onclick false so in this case what will be the common fix?
Hi Ayusman,
you can’t catch only the unexpected closing events (like refresh, close browser) — since they’re unexpected you don’t know what they will be before they appear. Therefore you need to catch ALL closing events and explicitly exclude those events you know about (i.e. your own links and buttons) by placing the . If you’re using JSF to create your website, it should be easy to add some code that makes the onclick appear automatically at each link (use a template or something).
Concerning your first question, can you post a whole html page with which I can reproduce the problem? You’ll need to html-escape all < and > signs like this: < and > else it will be scrambled by the wordpress software.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
<script type="text/javascript">
var needToConfirm = true;
window.onbeforeunload = confirmExit;
function confirmExit()
{
if (needToConfirm)
return "You have attempted to leave this page. If you have made any changes to the fields without clicking the Save button, your changes will be lost. Are you sure you want to exit this page?";
}
</script>
</head>
<body>
<a href="http://www.google.com">Test</a>
</body>
</html>
hello
The above script is working fine while closing browser, but if i press refresh button it alerts the pop up message. I need the pop up only at the time of closing the browser not refresh or navigation through the pages.
Thanks in advance.
Hi Kamatchi,
thanks for your comment. As far as I know, it’s not possible to distinguish between refresh and close events. But I’m not really an expert on this… I just copied the code from somewhere else.
Hi Ayusman,
sorry for the delay in replying to your last comment. I copied your code into a html file and opened it in my browser. It works as expected.
I added some code:
onclick="needToConfirm=false" to the google link, and then it deactivates the popup message as expected.
If you right-click the link and say “open in new window”, it does set the needToConfirm to false, too (similar effect when you add target="blank" to the link which opens the link in a new window) , but the main window is NOT relaoded and the needToConfirm remains false, and when you then refresh or close the main window, the warning message is not shown. That’s a problem indeed, for which I have no solution. Perhaps there’s some javascript action which can be executed AFTER a link was clicked, then we could use that to set needToConfirm=”true” again?
confirmClose=true;
function closeSession() {
if (confirmClose) {
if (confirm(‘Are you want to close the page?’)) {
$.ajax({
asyn: false,
url: ‘/BrowserClose.aspx’,
type: ‘Post’,
data: {},
contentType: “application/json; charset=utf-8″,
dataType: “json”,
success: function (msg) {
//alert(‘sucess’);
},
error: function (xhr, ajaxOptions, thrownError) {
//alert(xhr.status);
//alert(xhr.statusText);
//alert(thrownError);
}
});
} else { return ; }
}
}
window.onbeforeunload = closeSession;
i use ajax so pls give me soution
Sorry mate, I don’t handle “pls give me soution” requests.
well, *I* do answer them, if you, dear Bharani, tell me what the problem is? Is there any way I can reproduce it in my own browser/webserver?
if i using this code if user click browser close means ajax called and browser also closed pls give solution or sample page to how to use ajax when return value find to call ajax
function closeSession() {
//alert(confirmClose);
if (confirmClose) {
//if (confirm(‘Are you want to close the page?’)) {
////alert(‘/Login.aspx/hostoruser_Logout’);
//} else { return; }
return test();
}
}
var sucess = false;
var ajaxSubmit = false;
function test() {
if (sucess == true)
return “Are you want to close the page?”;
if (ajaxSubmit == false) {
ajaxSubmit = true;
$.ajax({
asyn: false,
url: ‘/BrowserClose.aspx’,
type: ‘Post’,
data: {},
contentType: “application/json; charset=utf-8″,
dataType: “json”,
success: function (msg) {
//alert(‘sucess’);
sucess = true;
},
error: function (xhr, ajaxOptions, thrownError) {
//alert(xhr.status);
//alert(xhr.statusText);
//alert(thrownError);
}
});
}
setTimeout(test(), 200);
}
window.onbeforeunload = closeSession;
this is code right now i use but it says “Too much of recursion”
function closeSession(){
if(confirmclose) {
return test(); /// i want to find retrun value and tehn use ajax function to update isActive field in user table
}
}
if the possible to find retrun value to call the ajax function
i need all these happen only when browser close [x] is clicked
var confirmClose = true;
var keyCode = 0;
function closeSession(evt){
if(confirmClose){
return ‘Bharani’; i want to find retrun value and tehn use ajax function to update isActive field in user table
}
}
window.onbeforeunload = closeSession;
<!– doSomething(event);–>
test
Google
i need all these happen only when browser close [x] is clicked
var confirmclose = true;
var sucess = false;
var ajaxSubmit = false;
function closeSession(){
if(confirmclose) {
return “close”; i want to find retrun value and tehn use ajax function to update isActive field in user table
}
}
window.onbeforeunload = closeSession;
test
fewfwef
i need all these happen only when browser close [x] is clicked
<!–
var confirmclose = true;
var sucess = false;
var ajaxSubmit = false;
function closeSession(){
if(confirmclose) {
return “close”;
}
}
window.onbeforeunload = closeSession;
test
Google
fewfwef
–>
Hi Bharani,
I don’t think you can find out the return value. Showing the popup message is the last thing that happens in the onbeforeunload event/method, and after that, javascript is not running any more, so you can’t do anything in your script to react to the user’s input. I’m sorry. You could do a workaround by storing the information that the user tried to close the window BEFORE showing the message, like this:
<html><body>
<script type="text/javascript">
triedToClose=false;
window.onbeforeunload = function() {
triedToClose = true
return "Did you save your stuff?"
}
function checkClosing() {
if (triedToClose) {
alert("user tried to close the window but changed his mind")
} else {
alert("user didn't try to close the window")
}
}
</script>
<pre>
To use:
1. click on the test link, see what happens.
2. try to close the window (browser (x)) - then select "stay on page"
3. click on the test link again - see that the message changed.
<a href="#" onclick="checkClosing()" rel="nofollow">Some test link</a>
</pre></body></html>
Please note that you can only evaluate the result if the user performs some action on your page, such as clicking on the test link. You would need to add the checkClosing() call to all your links and buttons and could even add it to the onbeforeunload function itself. not very elegant but the best I can do.
Hope this helps!
Hi schlumpf ,
I was done task thanks for your help. And one more help if possible to handle the browser close,minimize etc in javascript or jquery if possible means i need how to handle entire browser options and properties,event
Note: All browsers to handle
#Hi Bharani,
#I don’t think you can find out the return value. Showing the popup message is the last thing that happens in the onbeforeunload event/method, and after that, #javascript is not running any more, so you can’t do anything in your script to react to the user’s input. I’m sorry. You could do a workaround by storing the #information that the user tried to close the window BEFORE showing the message, like this:
ok but the return value is sent to where? i need that one so if we find means we can handle the allthings of browser is possible means we are done.
[email protected]
Hi Bharani,
the return value is sent to nowhere. Or if it is, I don’t know. I’m not a javascript expert, just stumbled over this solution on the web and wrote it down here. Sorry, can’t help you any further with that.
It helps a lot, thank you.
I could use this routine to check if the user has left out something before closing the window. Really thank you!
hi confirmation code is working fine,but i need to display the confirmation dailogue only on closing the browser window but not on cliking the refresh button of the window ,can you plz tell me how to do this?
Thanks in advance
Hi Vidya, thanks for your comment. It is not possible to distinguish between different browser close/reload events.
Thanks Vidya,
its working