Is window onbeforeunload depreciated? - javascript

I need to add an alert before the page closes and all online searches say to directly assign to window.onbeforeunload, as in window.onbeforeunload = function(), and return a string, but this is not working for me no matter what I do.
function unload(evt) {
return "UNLOAD";
};
console.log("SET1")
window.addEventListener('beforeunload', unload)
window.onbeforeunload = unload;
console.log("SET2");
This issue is ocurring in chrome specifically

Related

How do I use a custom confirmation method when window.onbeforeunload happens [duplicate]

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;
});

beforeunload() event to be triggered only when window/tab closed but not on any other condition [duplicate]

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;
});

Close Window Javascript

Is there a way i can create a javascript which will run the command onClick="my_onclick()" if they close the browser window? If so can you also make a popup that warns them If they close the window it will log out on the same script?
I am trying some variations of what i found but its not working for me.
$(document).ready(function()
{
$(window).bind("beforeunload", function() {
return confirm("If you confirm, you will be logged off the internet.");
});
});
I need it to return these paramters.
function my_onclick()
{URL = "http://%SERVERIP%/logout?%PARAMS%"; window.location.href=URL;}
The only 'event' available within Javascript that relates to the closing of a window is onbeforeunload, which expects to return a boolean (from the result of calling window.confirm().
It cannot be used to pass data back, since the page will already have expired. In short, no you can't do that.
You can use window.onbeforeunload, here's an example of what you need:
window.onbeforeunload = myConfirm;
function myConfirm(){
confirmMessage="If you confirm, you will be logged off !!";
return confirmMessage;
}

Javascript detect closing popup loaded with another domain

I am opening a popup window and attaching an onbeforeunload event to it like this:
win = window.open("http://www.google.com", "", "width=300px,height=300px");
win.onbeforeunload = function() {
//do your stuff here
alert("Closed");
};
If I leave the URL empty, the new popup opens with "about:blank" as the address but when I close it, I see the alert.
If I open in as you see it (with an external URL), once it's closed, I cannot see the alert anymore. Any idea why this is happening?
As mentioned, same origin policy prevents Javascript from detecting such events. But there's a quite simple solution which allows you to detect closure of such windows.
Here's the JS code:
var openDialog = function(uri, name, options, closeCallback) {
var win = window.open(uri, name, options);
var interval = window.setInterval(function() {
try {
if (win == null || win.closed) {
window.clearInterval(interval);
closeCallback(win);
}
}
catch (e) {
}
}, 1000);
return win;
};
What it does: it creates new window with provided parameters and then sets the checker function with 1s interval. The function then checks if the window object is present and has its closed property set to false. If either ot these is not true, this means, that the window is (probably) closed and we should fire the 'closeCallback function' callback.
This function should work with all modern browsers. Some time ago Opera caused errors when checking properties from windows on other domains - thus the try..catch block. But I've tested it now and it seems it works quite ok.
We used this technique to create 'facebook-style' login popups for sites which doesn't support them via SDK (ehem... Twitter... ehem). This required a little bit of extra work - we couldn't get any message from Twitter itself, but the Oauth redireced us back to our domain, and then we were able to put some data in popup window object which were accessible from the opener. Then in the close callback function we parsed those data and presented the actual results.
One drawback of this method is that the callback is invoked AFTER the window has been closed. Well, this is the best I was able to achieve with cross domain policies in place.
You could listen to the 'focus' event of the opener window which fires when the user closes the popup.
Unfortunately, you're trying to communicate across domains which is prohibited by JavaScript's same origin policy. You'd have to use a server-side proxy or some other ugly hack to get around it.
You could try creating a page on your site that loads the external website in an iframe. You could then pop open that page and listen for it to unload.
I combined #ThomasZ's answer with this one to set an interval limit (didn't want to use setTimeout).
Example (in Typescript, declared anonymously so as not lose reference to "this"):
private _callMethodWithInterval = (url: string, callback: function, delay: number, repetitions: number) => {
const newWindow = window.open(url, "WIndowName", null, true);
let x = 0;
let intervalID = window.setInterval(() => {
//stops interval if newWindow closed or doesn't exist
try {
if (newWindow == null || newWindow.closed) {
console.info("window closed - interval cleared")
callback();
window.clearInterval(intervalID);
}
}
catch (e) {
console.error(`newWindow never closed or null - ${e}`)
}
//stops interval after number of intervals
if (++x === repetitions) {
console.info("max intervals reached - interval cleared")
window.clearInterval(intervalID);
}
}, delay)
}//end _callMethodWithInterval

window.onbeforeunload in Chrome: what is the most recent fix?

Obviously, window.onbeforeunload has encountered its fair share of problems with Chrome as I've seen from all the problems I've encountered. What's the most recent work around?
The only thing I've got even close to working is this:
window.onbeforeunload = function () { return "alert" };
However, if I substitute return "alert" with something like alert("blah"), I get nothing from Chrome.
I saw in this question that Google purposefully blocks this. Good for them... but what if I want to make an AJAX call when someone closes the window? In my case, I want to know when someone has left the chatroom on my website, signalled by the window closing.
I want to know if there's a way to either
(a): fix the window.onbeforeunload call so that I can put AJAX in there
or
(b): get some other way of determining that a window has closed in Chrome
Answer:
$(window).on('beforeunload', function() {
var x =logout();
return x;
});
function logout(){
jQuery.ajax({
});
return 1+3;
}
A little mix and match, but it worked for me. The 1+3 makes sure that the logout function is being called (you'll see 4 if it's successful on the popup when you try to leave).
As of Chrome 98.0.4758.109 and Edge 100.0.1185.29, Chromium has not met the standard. There is a bug report filed, but the review is abandoned.
Test with StackBlitz!
Chrome requires returnValue to be a non-null value whether set as the return value from the handler or by reference on the event object.
The standard states that prompting can be controlled by canceling the event or setting the return value to a non-null value.
The standard states that authors should use Event.preventDefault() instead of returnValue.
The standard states that the message shown to the user is not customizable.
window.addEventListener('beforeunload', function (e) {
// Cancel the event as stated by the standard.
e.preventDefault();
// Chrome requires returnValue to be set.
e.returnValue = '';
});
window.location = 'about:blank';
Here's a more straightforward approach.
$(window).on('beforeunload', function() {
return "You should keep this page open.";
});
The returned message can be anything you want, including the empty string if you have nothing to add to the message that Chrome already shows. The result looks like this:
According to MDN,
The function should assign a string value to the returnValue property
of the Event object and return the same string.
This is the following
window.addEventListener( 'beforeunload', function(ev) {
return ev.returnValue = 'My reason';
})
This solved my problem why it wasn't working in my app:
Note that the user must interact with the page somehow (clicking somewhere) before closing its window, otherwise beforeunload is ignored in order not prevent abuse.

Categories

Resources