javascript's unload and beforeunload alternative - javascript

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.

Related

Determine if the user is reloading the current page in onunload

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

Page exit via hyperlink not being catched by onberforeunload

I have an onberforeunload method which is correctly alerting the user when they are trying to close the tab or the browser using the follwoing code:
window.onbeforeunload = function(event) {
event.returnValue = 'Are you sure you want to leave/';
console.log(event.returnValue);
};
I have discovered that the onberforeunload is not being called when I click a hyperlink on the page. The warning message I want to display isn't appearing and the page is loading freely.
I have searched for many ways to create a popup for when a hyperlink has been selected but they all deal with one or groups of hyperlinks in div tags. I wish for a popup to display if any hyperlink is selected.
Why isn't onbeforeunload catching the exiting of the page through a hyperlink? Is my understanding of onbeforeunload wrong that it should be catching hyperlink exits?
UPDATE
I have updated the code to the following:
window.onbeforeunload = closeIT;
function closeIT() {
return 'here';
if(searchOnGoing){
return 'Ifs you leave the Youtube History page now the application will not finish';
}
};
It is still not working for hyperlinks and working for browser and tab closure. I am running this as part of a content script in a chrome extension which is injecting the content script into the page. Would this have an effect on it?
I also have an onunload following,i am wondering would this also have an effect on it?
window.onunload = function(event){
//Do something
}
Actually, it should trigger. Do you catch the event somehow via a click-event-listener? Anyway, you could show an alert with help of a click-event listener.
Following code-snippet is copied from a similar question: how to detect if a link was clicked when window.onbeforeunload is triggered?
Here the question was, in contrast, how to prevent the beforeunload event when links are clicked.
var link_was_clicked = false;
document.addEventListener("click", function(e) {
if (e.target.nodeName.toLowerCase() === 'a') {
link_was_clicked = true;
}
}, true);
window.onbeforeunload = function() {
if(link_was_clicked) {
link_was_clicked = false;
return;
}
//other code here
}
The following snippet correctly uses onbeforeunload.
<body onbeforeunload="return myFunction()">
Click me!
<script>
function myFunction() {
return "Please don't go!\nThis works beautifully!";
}
</script>

load website in to a page via ajax or iframe and avoid navigation

This is what i need to do.
there is a web page and another website, both are hosted in same domain. i want to load that whole web site in to a div or iframe of that web page. similar example for this is a free proxy browser like hidemyass.com.
i know this can be easily done but the point is that i also need to avoid navigation. say that the web site has 2 pages called a.htm and b.htm . there is a link to b.htm from a.htm. so when some one click the link on a.htm, the browser will redirect to b.htm
when i embed that a.htm in a part of my page, if some one click the link; it will redirect to the b.htm in browser. what i want to do is that avoid that redirect and when some one click on the link, b.htm should load in my page itself.
i have no way to change that website(in this case a.htm and b.htm), everything should be done in that page.
how can i achieve this?
If you are only looking at link clicks and not navigation via JavaScript then the following code should do:
<iframe id="frame" src="a.html"></iframe>
<script type="text/javascript">
function onClick(event)
{
var link = event.target;
while (link && link.localName != "a")
link = link.parentNode;
if (link && !link.hasAttribute("target"))
link.setAttribute("target", "_parent");
}
// Listen to clicks inside the frame
document.getElementById("frame").contentWindow.addEventListener("click", onClick, false);
</script>
This will check the links the user clicks on and add target="_parent" attribute to them if no explicit target is defined. This means that links targeted at a new window/tab will still work as usual, links meant to replace the current page will replace the parent document instead. But this only works of course as long as the JavaScript code in a.html doesn't interfere.
If you only want to skip the link from your page only, you can add onclick handle to you link and return false when the frame has not completely loaded
this is the script
function checkLink(){
if (canNavigate){
return true;
}
return false;
}
but if you want to disable navigation on browser address you have to do like linkbuck website
http://c6f11ddd.linkbucks.com/url/http://www.google.com
linkbuck will not allow you to navigate away while ads has not been loaded yet.
They archive this by using these code, you should investigate it
Buster: function () {
var interval = setInterval(function () {
if (Lbjs.IsClick) {
clearInterval(interval);
}
else if (Lbjs.Unload > 0) {
Lbjs.Unload -= 2;
window.top.location.replace("/cancelnavigation/");
Lbjs.NavigationNotice();
}
}, 1);
var clearDelay = (this.Countdown > 0) ? this.Countdown : 8;
setTimeout(function () { clearInterval(interval); }, clearDelay * 1000);
},
NavigationNotice: function () {
var navNotice = document.getElementById("navNotice");
navNotice.innerHTML = "<span class=\"warning\" style=\"text-align:center;height:20px;width: 400px;padding: 10px;\"><b>Request Cancelled</b> - Navigation is disabled for 8 Seconds...</span>";
if (navNotice.style.display == "none") {
this.Fader.FadeIn(navNotice, 200, function () {
setTimeout(function () {
Lbjs.Fader.FadeOut(navNotice, 200, null);
}, 1500);
});
}

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