This question already has answers here:
Prevent safari loading from cache when back button is clicked
(8 answers)
Closed 4 years ago.
The issue I've found is very similar to this question, except that Safari on desktops seems to have resolved the issue. Essentially, the issue is this: when a client is browsing on mobile safari and the page executes a javascript function on pageA.html, then navigate to pageB.html, then press the back button to go back to pageA.html, the javascript function won't run when the client pressed the back button to come back to pageA.html. It will skip the javascript call.
I've tried the solutions mentioned in the link above, but nothing seems to work for mobile Safari. Has anyone else encountered this bug? How did you handle it?
This 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.
window.onpageshow = function(event) {
if (event.persisted) {
alert("From back / forward cache.");
}
};
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 back / forward cache.");
}
});
Quick solution to these problem is to reload the page when back button is pressed. This however nullifies any positive effect back / forward cache would give.
window.onpageshow = function(event) {
if (event.persisted) {
window.location.reload()
}
};
As a sidenote, you can see lot of pages offering using empty onunload handler as solution. This has not worked since iOS5.
$(window).bind("unload", function() { });
Related
Does anyone know a way, via JavaScript, that I can either clear Safari's bfcache, or force it to reload rather that used a cached version of a page?
I have a web application that is running tests, and there is JavaScript which monitors a countdown (a timeout):
timeoutId = window.setInterval(function () {
timeoutRemaining--;
if (timeoutRemaining <= 0) {
location.href = myTimeoutLocation;
}
}, timeoutInterval);
This all works fine until I get to myTimeoutLocation. The behavior is that, if a user clicks the back button, the test should continue. However, when navigating back, I find that IE and Chrome reload the page, but Firefox and Safari are showing the cached page. I need to make sure that a cached page is NEVER shown. I can fix this problem in Firefox by adding:
window.onunload = function () { };
to my script, but that hasn't worked in Safari since Safari 5.x (as far as I can tell). I found another solution:
window.addEventListener("pageshow", function(evt){
if(evt.persisted){
setTimeout(function(){
window.location.reload();
},10);
}
}, false);
This worked to an extent... The problem I have now is that even with the above code, I am receiving a dialog box: ... which I'm apparently not allowed to embed. The dialog says that in order to display the page, information must be sent to the server, with the appropriate confirm or deny buttons. I did try setting forceGet to true, but that did not solve the problem with the dialog appearing. I should mention that clicking Resend has the desired effect.
Non-embedded image of dialog
And yes, I realize the image is of Firefox, not Safari.
In case it makes any difference (even though this is a JavaScript question), the site is coded in .NET/MVC4 and is hosted in IIS.
Thank you in advance for any help/thoughts/information/pointers in the right direction.
I can't find a way to execute a script when a page is reached via the browser's BACK button or key command. (Background: I need to know if a page was opened using the browser's BACK button or key command. Then I could check for a stored sessionStorage varible and trigger some appropriate stuff).
If, for example, I put this into my page code
<script>
$(document).ready(function() {
alert("YES!");
/* in the real situation: do something */
})
</script>
, the alert will be displayed when I load the page via a link or by opening it directly by typing its URL into the address bar.
But this alert will not appear when I come to that page via the BACK button.
I tried the same using $(window).on("load", function() {... and $(window).on("navigate", function () {... - no success either...
EDIT / ADDITION:
I just realized that browsers behave differently in this respect: Chrome, Opera, IE and Firefox Windows will reload the page correctly (and trigger document.ready() and onload() events) , but Firefox Mac and Safari will not - they load the whole page from cache without triggering document.ready() or onload(). (I haven't tried mobile browsers yet)
So i searched for solutions avoiding the cached content, but what I've found and tried so far (which is a lot!) hasn't worked either...
after reading lots of posts and trying the solutions in there and narrowing the thing down to a browser issue, I discovered this answer, which forces the page to be reloaded also in Safari (and apparently also Firefox/Mac):
https://stackoverflow.com/a/13123626/5641669
Essentially, this jQuery code reloads the page in its original state when coming there via the back button on Safari, which also allows to trigger any desired script on pageload:
$(window).bind("pageshow", function(event) {
if (event.originalEvent.persisted) {
window.location.reload()
}
});
I'm trying to use pageshow event on safari (iphone) to fix some problems with back button cache. But it seems to work only one time when using back button.
I have this handler on page A:
window.addEventListener("pageshow", function () {
alert("pageshow");
});
Then i go to page B and go back to A - everything works fine. But when I go to page B again and go back to A again, then nothing happens.
example:
go to this fiddle: https://jsfiddle.net/y278q8q0/, then navigate to any other page and play with back and forward buttons. The event will fire only once.
That how it looks on iphone 6 with ios 8.4:
https://vid.me/5WPe
edit:
question was marked as a duplicate of this one: 'pageshow' is not received when pressing "back" button on Safari on *IPad"
It's hard to say if those problems have the same cause. In my case event always fires once at the beginning. Also I tried to implement all non-jquery solutions from mentioned question and none of them is working for me.
This question already has answers here:
JavaScript, browsers, window close - send an AJAX request or run a script on window closing
(9 answers)
Closed 6 years ago.
I've got a game that runs in the web browser (as a plugin) and what I'm trying to do is:
Detect if the user has decided to close the browser (Alt+F4, hitting the 'X' button etc)
Prevent the browser from closing whilst we fire a call to our web services to log that the user has closed the browser
Once we receive the response from the web services, release the lock and allow the browser to close as requested.
The main reason we want to do this is we're having some concurrency problems and going through our logs we want to isolate people logging out / closing the browser from genuine instances where the plugin has crashed.
I looked into doing this with JQuery (for X-Browser compatability - Opera won't work but we don't have any users on Opera anyway thankfully):
$(window).bind('beforeunload', function(e) {
e.preventDefault();
// make AJAX call
});
The problem is that this displays a confirmation dialog to the user ('Are you sure you want to leave this page') which the user might confirm before the AJAX call is sent.
So the question is, is there a way of preventing the browser from closing until the response is received? Also 'beforeunload' fires when the page is changed as well - is there a way of distinguishing clicking on a link from actually clicking close?
Grateful for any help wrt to this!
Its tricky business to avoid the browser window from beeing closed. Actually, there is no way to do that, beside returning a non-undefined value from the onbeforeunload event, like you described.
There is one possible suggestion I can make, that is creating a synchronized ajax request within the onbeforeunload event. For instance
window.onbeforeunload = function() {
$.ajax({
url: '/foo',
type: 'GET',
async: false,
timeout: 4000
});
};
In theory, this will block the browser for a maximum of 4 seconds. In reality, browsers will treat this differently. For instance, Firefox (I tested it on 9), will indeed not close the window immediately, but it also does not respect the timeout value there. I guess there is an internal maximum of like 2 seconds before the request is canceled and the window/tab gets closed. However, that should be enough in most cases I guess.
Your other question (how to distinguish between clicking a link), is fairly simple. As described above, onbeforeunload looks what is getting returned from its event handlers. So lets assume we have a variable which is global for our application, we could do something like
var globalIndicator = true;
// ... lots of code
window.onbeforeunload = function() {
return globalIndicator;
};
At this point, we would always receive a confirmation dialog when the window/tab is about to get closed. If we want to avoid that for any anchor-click, we could patch it like
$( 'a[href^=http]' ).on('click', function() {
globalIndicator = undefined;
});
As for the first part of your question, there is no reliable way of preventing the browser from closing other than using window.onbeforeunload. The browser is there to serve the user and if the user chooses to close his browser then it will do so.
For your second question, it is reasonably easy to distinguish a click on a link from other events triggering an onbeforeunload event by jQuery:
$('a').click(function(e) {...});
You could use this, for example, to make sure a click will not trigger unbeforeunload:
$('a').click(function(e) {window.onbeforeunload = null});
You can use below code to prevent the browser from getting closed:-
window.onbeforeunload = function() {
//Your code goes here.
return "";
}
Now when user closes the browser then he gets the confirmation dialogue because of return ""; & waits for user's confirmation & this waiting time makes the request to reach the server.
I'm pretty sure that what you want isn't possible using JavaScript. But since you have a browser plugin, shouldn't you be able to check whether your plugin object was cleaned up correctly? I'm not sure if you're using ActiveX, NPAPI or something like Firebreath, but these frameworks all have lifecycle methods that will be called on your plugin in the event of a normal shutdown, so you should be able to write something to the logs at this point. If the plugin crashes, these won't be called.
I know this is not recommended, but I need it because I have an iframe inside the page who has the actual content and I want that when the users hits refresh button, iframe reloads not entire page.
I know I have to call onunload / onbeforeunload event, but I don't want to ask me if I want to leave the window, just don't.
Is that possible? I've got handled the F5 key, but I like to prevent refreshing from button too.
UPDATE: I wrote this 5 years ago, browsers do different stuff now, you can still use this for testing your browser set, but your experience may vary from my old research.
Experimenting using jQuery, because I'm lazy.
Theoretically, preventing the default behavior should stop the event from doing whatever it is supposed to do. It doesn't work with the events in my example and has different results in different browsers. I put the Math.random() in to determine if the page has been reloaded or not. Because different browsers do different things, I highly recommend NOT using this in a production environment.
<body>
<p></p>
<script type="text/javascript">
$('p').append(Math.random());
$(window).bind({
beforeunload: function(ev) {
ev.preventDefault();
},
unload: function(ev) {
ev.preventDefault();
}
});
</script>
</body>
Using CTRL-R or F5 or Reload Button:
Safari: Does nothing
Chrome: Does nothing
Opera 10 & 11: Does nothing
Firefox 7.x: Shows a special prompt with two buttons:
Stay on Page - Does not reload page
Leave Page - Reloads the page
IE7 & IE8: Shows a prompt with two buttons:
OK - Reloads the page
Cancel - Does not reload the page
IE9: Shows a prompt with two buttons:
Leave this page - reloads
Stay on this page - does not reload
Firefox Prompt (you can tell I tested it on a Mac)
IE7 & IE8 Prompt
IE9 Prompt
In closing:
Yes, I did not test IE6, I deleted my VM which had it installed, I don't have a VM with IE10 beta installed, so you're out of luck on that too.
You might also experiment with cancelBubble and stopPropagation or maybe return false; might reveal something useful. I'm down with Jordan's reply that you shouldn't be trying to override the defaults, so I'm concluding my experiment here.
Returning false in an onsubmit event prevents the form from being submitted and stays in the same page without any user interaction..
For example..
when a form having input field is empty and submitted this javascript check for validation and returns accordingly..
If false is returned nothing is done(i.e. page is not refreshed or redirected)..
If the validation is ok and if true is returned the form action is performed..
function validateForm(Str) {
mystring=document.getElementById('inputid').value;
if(!mystring.match(/\S/)){
alert ('Please Enter a String.Field cannot be empty');
return false;
}else{
return true;
}
}