Determine if the user is reloading the current page in onunload - javascript

Is it possible to determine if the user is reloading the current page from within the events window.onunload or window.onbeforeunload?
I need to determine if the user is reloading the page and if they are stop my code from deleting a cookie.
window.onunload = window.onbeforeunload = function(e) {
// How can I detect a page refresh?
if (USER_NOT_REFRESHING)
$.removeCookie("my_session", { path: '/' });
else {
// user is refreshing
}
}

No, it's not possible. The browser only indicates the user is leaving, not why.

You can try using the PerformanceNavigation API
So, if the browser supports performance navigation, then you can check for reload by doing:
if(performance.navigation.type===1) {
// it's a reload
}
The above method may not work for code snippets

Related

Jquery Cookie : one time use cookie

I want to put cookie to my page.
Here's the logic :
When I load the page, I want it to load a popup or bootstrap modal. But the modal only load once when the browser is active. And only will load again when the browser tab is closed or exits the browser application. I have used session to do this, but I prefer to use cookie for personal preferences.
Is there a way to do this with javascript?
I've tried with $(window).load(), and $(window).on('beforeunload',function());
Javascript :
<script type="text/javascript">
$(window).load(function () {
if( $.cookie('firstLoad') == 'unloaded' || $.cookie('firstLoad') == 'null' || $.cookie('firstLoad') == null ) {
$('#openLoading').modal('show');
var time_exp = 1;
$.cookie('firstLoad','loaded',{ expires: time_exp });
}
});
$(window).on('beforeunload', function (){
alert($.cookie('firstLoad'));
$.cookie('firstLoad','unloaded');
});
</script>
The problem is sometimes the app browser will execute location.reload() and will reset the cookie in some way and make the popup appear again.
Please provide solution, thanks.
PS : the var time_exp and expires : time_exp is a last resort if the unload doesn't work
The beforeunload event doesn't just fire when the tab is closed. It will fire whenever the user goes to a new page in the same tab, including a page on your site. So you are resetting your cookie every time the user navigates between pages.
There is no event you can use to tell you the user is leaving your site specifically. The closest you can do is not set an expires, so that the cookie will automatically be deleted when the browser exits.
You could put a close button in the modal, and set a cookie when it is clicked so you know the user has viewed the modal and you don't need to show it again for however long you decide.

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

javascript's unload and beforeunload alternative

I need to monitor when the user moves away from a page (to a different site not the same site) or closes the window/tab. I can achieve that with $(window).bind('unload', function() {}); but onload is a catch-all event: it also catches page refresh and navigating to a different page on the same website. How can I detect those two events (page refresh and navigating to another page in the same website) using javascript/jQuery please?
I think that isn't possible, I don't know such an event.
A possible solution is to compare the current url with the destination url but that's not possible because of security and privacy reasons see:
How can i get the destination url in javascript onbeforeunload event?
On each page,
var leaving = true;
$(function() {
$('a[rel!=ext]').click(function () { leaving = false; });
$('form').submit(function () { leaving = false; });
});
$(function() { window.onbeforeunload = unloadPage; });
function unloadPage() {
if(leaving) {
// Put your logic here
}
}
Then just make sure that all links to external sites have a rel="ext" attribute.

Prevent safari loading from cache when back button is clicked

Got an issue with safari loading old youtube videos when back button is clicked. I have tried adding onunload="" (mentioned here Preventing cache on back-button in Safari 5) to the body tag but it doesn't work in this case.
Is there any way to prevent safari loading from cache on a certain page?
Your problem is caused by back-forward cache. It is supposed to save complete state of page when user navigates away. When user navigates back with back button page can be loaded from cache very quickly. This is different from normal cache which only caches HTML code.
When page is loaded for bfcache onload event wont be triggered. Instead you can check the persisted property of the onpageshow event. It is set to false on initial page load. When page is loaded from bfcache it is set to true.
Kludgish solution is to force a reload when page is loaded from bfcache.
window.onpageshow = function(event) {
if (event.persisted) {
window.location.reload()
}
};
If you are using jQuery then do:
$(window).bind("pageshow", function(event) {
if (event.originalEvent.persisted) {
window.location.reload()
}
});
All of those answer are a bit of the hack. In modern browsers (safari) only on onpageshow solution work,
window.onpageshow = function (event) {
if (event.persisted) {
window.location.reload();
}
};
but on slow devices sometimes you will see for a split second previous cached view before it will be reloaded. Proper way to deal with this problem is to set properly Cache-Control on the server response to one bellow
'Cache-Control', 'no-cache, max-age=0, must-revalidate, no-store'
Yes the Safari browser does not handle back/foreward button cache the same like Firefox and Chrome does. Specially iframes like vimeo or youtube videos are cached hardly although there is a new iframe.src.
I found three ways to handle this. Choose the best for your case.
Solutions tested on Firefox 53 and Safari 10.1
1. Detect if user is using the back/foreward button, then reload whole page or reload only the cached iframes by replacing the src
if (!!window.performance && window.performance.navigation.type === 2) {
// value 2 means "The page was accessed by navigating into the history"
console.log('Reloading');
//window.location.reload(); // reload whole page
$('iframe').attr('src', function (i, val) { return val; }); // reload only iframes
}
2. reload whole page if page is cached
window.onpageshow = function (event) {
if (event.persisted) {
window.location.reload();
}
};
3. remove the page from history so users can't visit the page again by back/forward buttons
$(function () {
//replace() does not keep the originating page in the session history,
document.location.replace("/Exercises#nocache"); // clear the last entry in the history and redirect to new url
});
You can use an anchor, and watch the value of the document's location href;
Start off with http://acme.co/, append something to the location, like '#b';
So, now your URL is http://acme.co/#b, when a person hits the back button, it goes back to http://acme.co, and the interval check function sees the lack of the hash tag we set, clears the interval, and loads the referring URL with a time-stamp appended to it.
There are some side-effects, but I'll leave you to figure those out ;)
<script>
document.location.hash = "#b";
var referrer = document.referrer;
// setup an interval to watch for the removal of the hash tag
var hashcheck = setInterval(function(){
if(document.location.hash!="#b") {
// clear the interval
clearInterval(hashCheck);
var ticks = new Date().getTime();
// load the referring page with a timestamp at the end to avoid caching
document.location.href.replace(referrer+'?'+ticks);
}
},100);
</script>
This is untested but it should work with minimal tweaking.
The behavior is related to Safari's Back/Forward cache. You can learn about it on the relevant Apple documentation: http://web.archive.org/web/20070612072521/http://developer.apple.com/internet/safari/faq.html#anchor5
Apple's own fix suggestion is to add an empty iframe on your page:
<iframe style="height:0px;width:0px;visibility:hidden" src="about:blank">
this frame prevents back forward cache
</iframe>
(The previous accepted answer seems valid too, just wanted to chip in documentation and another potential fix)
I had the same issue with using 3 different anchor links to the next page. When coming back from the next page and choosing a different anchor the link did not change.
so I had
House 1
View House 2
View House 3
Changed to
House 1
View House 2
View House 3
Also used for safety:
// Javascript
window.onpageshow = function(event) {
if (event.persisted) {
window.location.reload()
}
};
// JQuery
$(window).bind("pageshow", function(event) {
if (event.originalEvent.persisted) {
window.location.reload()
}
});
None of the solutions found online to unload, reload and reload(true) singularily didn't work. Hope this helps someone with the same situation.
First of all insert field in your code:
<input id="reloadValue" type="hidden" name="reloadValue" value="" />
then run jQuery:
jQuery(document).ready(function()
{
var d = new Date();
d = d.getTime();
if (jQuery('#reloadValue').val().length == 0)
{
jQuery('#reloadValue').val(d);
jQuery('body').show();
}
else
{
jQuery('#reloadValue').val('');
location.reload();
}
});
There are many ways to disable the bfcache. The easiest one is to set an 'unload' handler. I think it was a huge mistake to make 'unload' and 'beforeunload' handlers disable the bfcache, but that's what they did (if you want to have one of those handlers and still make the bfcache work, you can remove the beforeunload handler inside the beforeunload handler).
window.addEventListener('unload', function() {})
Read more here:
https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/1.5/Using_Firefox_1.5_caching

How to tell if a web page is being exited/unloaded via flash versus via normal HTML

I have a flash app, that redirects to another page.
I'd love to trap any other window unload event (clicking links / submitting forms) and warn the user they'll lose their progress in the Flash app.
However, I can't find any way to tell that the click/change of URL/window unload was triggered by Flash vs being triggered by a normal link etc.
Is there any way to detect this, and how reliable is it?
There's no way to tell what caused an unload event directly in the event handler. However, you might be able to achieve this by attaching an onclick event handler to every link on the page that sets a variable. In jQuery:
$("A").click(function(){window.clickedLink = this});
You might read the clickedLink in your unload event and tell the difference.
How do you redirect to the other page from Flash?
What you can do is redirect with a Javascript-function, and call this from Flash (with ExternalInterface). When you call this redirect, you set a certain flag, indicating you're redirecting from Flash. Then set a listener for the window unload event, and check if the flag is set. If not, you can show the message to the user. Otherwise, just skip this and redirect.
<script>
var callFromFlash = false;
window.unload = unloadPage;
//call this function from Flash using ExternalInterface
function doRedirect(url)
{
callFromFlash = true;
//redirecting
window.location.href = url;
}
function unloadPage()
{
if(!callFromFlash)
{
//show message and wait for response
}
}
</script>

Categories