Beforeunload event does not fire after page refresh Chrome - javascript

I have this simple code
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<!--<script src="angular.min.js"></script>-->
<script>
window.onload = function () {
window.addEventListener("unload", function () {
debugger;
});
window.addEventListener("beforeunload", function () {
debugger;
});
window.onbeforeunload = function () {
}
}
</script>
</head>
<body ng-app="app">
</body>
</html>
I want unload or beforeunload events be fired after I refresh the page. This is not happening in Chrome Versión 67.0.3396.62. I have tried firefox and edge and it works well. It also works when i close the tab. The error ocurrs only when i refresh the page.

You've run into an issue that was already reported. It looks like a bug, but according to a Chrome dev (kozy) it is a feature:
Thanks for repro. It is actually feature. As soon as you pressed reload we ignore all breakpoints before page reloaded. It is useful all the time when you have a lot of breakpoints and need to reload page to restart debugging session.
Workaround: instead of pressing reload button you can navigate to the same url using omnibox then all breakpoint will work as expected.
I've added bold emphasis to point out the workaround proposed by kozy. I've tried it and found that it works.
Other than the issue with the debugger statement, the handlers are executed whether you are reloading or closing the tab. In both cases that follow, I get the stock prompt that Chrome provides when returning true:
window.addEventListener("beforeunload", function (ev) {
ev.returnValue = true; // `return true` won't work here.
});
This works too:
window.onbeforeunload = function () {
return true;
}
It used to be that you could use a return value with a message and the browser would show your custom message but browsers generally no longer support this.
Whether or not you want to set the handler for beforeunload inside a handler for load is entirely dependent on your goals. For instance, I have an application for editing documents that does not set the beforeunload handler until the application has started initializing, which is much later than the load event. The beforeunload handler is there to make sure the user does not leave the page with unsaved modifications.

Related

Document ready form submission and browser history

I have the following code in my page to submit the form on the page automatically when the DOM is ready:
$(function () {
$('form').submit();
});
However, on the next page if the user clicks back on their browser it goes back to the page before this one rather than the page with this code on (with Chrome/IE anyway). i.e. the page with the form on is missing in the browser history.
This is great, although I wondered is this something all modern browsers now do? I am looking for an answer that cites official sources such as from internet standards documents or from browser vendors that state the mechanism they have implemented.
This appears to only happen if I call the submit() function in the DOM ready or Window load events.
e.g. this code will show the form page in browser history after the page is clicked (back/forward):-
document.addEventListener('click', function () { document.forms[0].submit(); }, false);
the following snippets won't:-
document.addEventListener('DOMContentLoaded', function () { document.forms[0].submit(); }, false);
window.addEventListener('load', function() { document.forms[0].submit(); }, false);
window.onload = function () { document.forms[0].submit(); };
I've dealt with this before. I did not want the back button to take
the user back to previous page. Using onbeforeunload solved the
issue for me...
But your issue is related to the following concepts
Browsing Context
Session History
Replacement Enabled (flag)
A "Browsing Context" is an environment in which "Document" objects
are presented to the user.
The sequence of "Document"s in a "Browsing Context" is its "Session History". The
"Session History" lists these "Document"s as flat entries.
"Replacement Enabled" comes into effect when we propagate from one "Document" to another in the "Session History". If the traversal was initiated with "Replacement Enabled", the entry immediately before the specified entry (in the "Session History") is removed.
Note A tab or window in a Web browser typically contains a browsing context, as does an iframe or frames in a frameset.
Logically thinking, by calling any of these
document.addEventListener( 'DOMContentLoaded', function() {document.forms[0].submit();}, false );
window.addEventListener( 'load', function() {document.forms[0].submit();}, false );
window.onload = function() {document.forms[0].submit();};
you are suggesting the browser to perform #3, because what those calls mean
is that propagate away from the page as soon as it loads. Even to me that code is
obviously :) asking to be cleared off from the "Session History".
Further reading...
onbeforeunload
browsers
browsing-context
unloading-documents
replacement-enabled
Since this code leaves the page in the history when responding to the click event:-
document.addEventListener('click', function () { document.forms[0].submit(); }, false);
and the following pieces of code do not leave the page in history (DOMContentLoaded, and window onload events):-
document.addEventListener('DOMContentLoaded', function () { document.forms[0].submit(); }, false);
window.addEventListener('load', function() { document.forms[0].submit(); }, false);
window.onload = function () { document.forms[0].submit(); };
it can be assumed that modern browsers do not record a navigation history for page navigation that occurs within the window load or document ready handlers.
When the user hits the back button, the browser shows the cached copy of the page. Form submit doesn't cache the page therefore it doesn't show up in your history.
Yes, redirecting from an onload event handler causes the new URL to replace the one you leave in the history (and thus doesn't add a useless entry). But that's not the only trigger for that replacement, it may also be caused by any location change occurring fast enough, this delay being designed to avoid polluting the history in case of JavaScript based re-directions.
It is very hard to find any specification on that topic but on Firefox this delay seems to be 15 seconds. Here's a mention of this delay in bugzilla from one of the moz developers :
Mozilla uses a threshold of 15 seconds to decide if a page should
stay in history or not. If a site uses and
redirects to another site with in 15 seconds OR redirects to another
page in onLoadHandler() etc ..., the redirected page will replace
(and thereby eliminating) the redirecting page from history. If the
redirection happens after 15 seconds, the redirecting page stays in
history.
One may argue about the
time limit. But this is just something we thought was a reasonable number

Using onafterprint in Chrome & Safari

I am aware that until recently onafterprint was only native to IE. Recently HTML5 has added it to its list of events. I have only been successful in using it in Firefox but cannot get it to function in Chrome or Safari.
It appears to only function in Firefox when its used in the body:
<body onafterprint="printIt()">
The script for the function is this:
$(document).ready(function() {
$('.printMe').click(function() {
window.print();
return false;
});
});
function printIt()
{
$('#confirmPrint').show();
};
By clicking the .printMe button, it opens the print window. Clicking print or cancel will show a message in #confirmPrint. I'm not so worried about being able to tell whether they are clicking cancel or print. I am only concerned with it functioning in Chrome and Safari. Any help is much appreciated. I am using jQuery as well, if that is not already obvious.
After some experiments, I think I can safely say that onafterprint is not worth considering.
Firefox fires it even if the user clicked Cancel instead of OK in the print dialog
IE8 apparently fires it even before the print dialog appears
Chrome doesn't fire it at all
Instead, just do whatever you wanted to do directly after calling print(), i.e.
$(document).ready(function() {
$('.printMe').click(function() {
window.print();
printIt();
return false;
});
});
function printIt()
{
$('#confirmPrint').show();
};

Window.onbeforeprint and Window.onafterprint get fired at the same time

I have defined onbeforeprint and I modify my html code and now once I finish printing that is on select of print button I want the onafterprint to be fired but it does not.
Instead when I press the Control + Print button the onbeforeprint is fired first and then the onafterprint event and then print dialog is shown.
Is there any way I could in some way do changes to my html after the Print button is clicked?
Am using IE -9 browser and the code is as follows:
Code
<script type="text/javascript">
window.onbeforeprint = function () {
alert('Hello');
}
window.onafterprint = function () {
alert('Bye');
}
</script>
onbeforeprint fired before dialog appears and allows one to change html and so on.
onafterprint is fired just before dialog appears. It is not even possible to know, whether document was actually printed or user canceled it. Needless to say about when printing finished (if started at all).
Again: no event is available to track anything happened in print dialog, i.e. answer to your question is no.
Moreover, I hope what your need will never be implemented, cause this allows to frustrate user. He/she asks to print one document, but got something different.
I ran into this same issue trying to use the onafterprint event, even in modern browsers.
Based on one of the other answers here, I was able to come up with this solution. It let's me close the window after the print dialog is closed:
// When the new window opens, immediately launch a print command,
// then queue up a window close action that will hang while the print dialog is still open.
// So far works in every browser tested(2020-09-22): IE/Chrome/Edge/Firefox
window.print();
setTimeout(function () {
window.close(); // Replace this line with your own 'afterprint' logic.
}, 2000);
Yes, you can, no catch. I have thus implemented in a professional application.
Print in Explorer, Firefox, all
window.onload = PrintMe;
function PrintMe() {
window.print();
setTimeout(function () {
alert("OK");
// Here you code, for example __doPostBack('ReturnPrint', '');
}, 2000);
}

Prompt User before browser close?

We have an administrative portal that our teachers constantly forget to download their latest PDF instructions before logging out and/or closing the browser window. I have looked around but can't find what I'm looking for.
I want to accomplish the following goals:
Goal 1
Before a user can close the browser window, they are prompted "Did you remember to download your form?" with two options, yes/no. If yes, close, if no, return to page.
Goal 2
Before a user can click the 'logout' button, they are prompted with the same as above.
My first pass at the very basic code (which does not work for browser close) is:
<!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=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript">
function init() {
if (window.addEventListener) {
window.addEventListener("beforeunload", unloadMess, false);
} else if (window.onbeforeunload) {
window.onbeforeunload = unloadMess;
};
}
function unloadMess() {
var User_Message = "[Your user message here]"
return User_Message;
}
</script>
</head>
<body onload="init();">
hello this is my site
</body>
</html>
EDIT - NEW ISSUES
The solution provided below works but also has its own issues:
When user clicks the link to actually download the forms, the page thinks they are trying to leave and in turn present an error message to them! Also - I would like for one event or another to occur but not necessarily both. I.e. they hit 'logout' button and they are presented with the OnClick event, THEN the browser prompt. Any ideas?
Update 2017
All modern browsers do not support custom messages any longer.
window.onbeforeunload = function(evt) {
return true;
}
This one for closing the tab:
window.onbeforeunload = function(evt) {
var message = 'Did you remember to download your form?';
if (typeof evt == 'undefined') {
evt = window.event;
}
if (evt) {
evt.returnValue = message;
}
return message;
}
and use onClick event for logout button:
onClick="return confirm('Did you remember to download your form?');"
I think that this may be part of your problem:
else if(window.onbeforeunload) {
window.onbeforeunload = unloadMess;
};
That test in the "if" statement will only be true if there's already a handler function. That test doesn't mean, "does the window object have an 'onbeforeunload' property?". It means, "is the 'onbeforeunload' property of the window currently not null?".
I think it'd be safe to just set "onbeforeunload" directly, for any browser.
You cannot alert or things like that in onbeforeunload, you cannot simply return false to make the user not leave the page, as with other events like onclick. This would allow a site to make it impossible to leave it.
You can however just return a string, the browser then shows a confirm dialog including your string asking the user whether they really want to leave.
Pointy is right about browser close events - imagine if evil sites could prevent you from closing their windows?? So you cannot prevent them from closing your site, but you can do an alert.
As far as your logout button is concerned, that is much more straight-forward:
Logout

After travelling back in Firefox history, JavaScript won't run

When I use the back button on Firefox to reach a previously visited page, scripts on that page won't run again.
Is there any fix/workaround to have the scripts execute again when viewing the page the second time?
Please note that I have tested the same pages on Google Chrome and Internet Explorer and they work as intended.
Here are the files and the steps I used to test the problem:
(navigate to 0.html, click to get to 1.html, back button)
0.html
<html><body>
<script>
window.onload = function() { alert('window.onload alert'); };
alert('inline alert');
</script>
Click Me!
</body></html>
1.html
<html><body>
<p>Go BACK!</p>
</body></html>
Set an empty function to be called on window.onunload:
window.onunload = function(){};
e.g.
<html><body>
<script type="text/javascript">
window.onload = function() { alert('window.onload alert'); };
window.onunload = function(){};
alert('inline alert');
</script>
Click Me!
</body></html>
Source:
http://www.firefoxanswer.com/firefox/672-firefoxanswer.html (Archived Version)
When I use the back button on Firefox to reach a previously visited page, scripts on that page won't run again.
That's correct and that's a good thing.
When you hit a link in Firefox (and Safari, and Opera), it does not immediately destroy your page to go onto the next one. It keeps the page intact, merely hiding it from view. Should you hit the back button, it will then bring the old page back into view, without having to load the document again; this is much faster, resulting in smoother back/forward page transitions for the user.
This feature is called the bfcache.
Any content you added to the page during the user's previous load and use of it will still be there. Any event handlers you attached to page elements will still be attached. Any timeouts/intervals you set will still be active. So there's rarely any reason you need to know that you have been hidden and re-shown. It would be wrong to call onload or inline script code again, because any binding and content generation you did in that function would be executing a second time over the same content, with potentially disastrous results. (eg. document.write in inline script would totally destroy the page.)
The reason writing to window.onunload has an effect is that the browsers that implement bfcache have decided that — for compatibility with pages that really do need to know when they're being discarded — any page that declares an interest in knowing when onunload occurs will cause the bfcache to be disabled. That page will be loaded fresh when you go back to it, instead of fetched from the bfcache.
So if you set window.onunload= function() {};, what you're actually doing is deliberately breaking the bfcache. This will result in your pages being slow to navigate, and should not be used except as a last resort.
If you do need to know when the user leaves or comes back to your page, without messing up the bfcache, you can trap the onpageshow and onpagehide events instead:
window.onload=window.onpageshow= function() {
alert('Hello!');
};
You can check the persisted property of the pageshow event. It is set to false on initial page load. When page is loaded from cache it is set to true.
window.onpageshow = function(event) {
if (event.persisted) {
alert("From bfcache");
}
};
For some reason jQuery does not have this property in the event. You can find it from original event though.
$(window).bind("pageshow", function(event) {
if (event.originalEvent.persisted) {
alert("From bfcache");
}
});
In my case window.onunload with an empty function didn't help (I tried to set a value for dropdown when user uses backwards button). And window.onload didn't work for other reason - it was overridden by <body onload="...">.
So I tried this using jQuery and it worked like a charm:
$(window).on('pageshow', function() { alert("I'm happy"); });
Wire in an "onunload" event that does nothing:
<html><body>
<script type="text/javascript">
window.onload = function() { alert('window.onload alert'); };
window.onunload = function(){};
alert('inline alert');
</script>
Click Me!
</body></html>
As far as i know Firefox does not fire onLoad event on back.
It should trigger onFocus instead based from this link here.
A simple way to cause a page to execute JavaScript when the user navigates back to it using browser history is the OnPopState event. We use this to pause and replay the video on our home page (https://fynydd.com).
window.onpopstate = function() {
// Do stuff here...
};
for some cases like ajax operations url change listener can be used
$(window).on('hashchange', function() {
....
});

Categories