I'm trying to make a simple loading spinner that pops up when navigating. It shows up using a 'beforeunload' event when navigating away and uses the 'load' event to hide itself again when it is done.
The problem is that when I leave the page in the background on my phone for e.g. a few hours the 'beforeunload' event triggers and displays the spinner. Probably because Chrome on Android is partially unloading the page to save memory. The spinner doesn't go away by itself though and I can't seem to figure out how to make it disappear again in an elegant way.
Is there any other event I should be using instead?
window.addEventListener("load", function() {
topSpinner.classList.add("closed");
});
window.addEventListener("beforeunload", function() {
topSpinner.classList.remove("closed");
});
I'm trying to make a simple loading spinner that pops up when navigating. It shows up using a 'beforeunload' event when navigating away and uses the 'load' event to hide itself again when it is done.
The problem is that when I leave the page in the background on my phone for e.g. a few hours the 'beforeunload' event triggers and displays the spinner. Probably because Chrome on Android is partially unloading the page to save memory. The spinner doesn't go away by itself though and I can't seem to figure out how to make it disappear again in an elegant way.
Is there any other event I should be using instead?
window.addEventListener("load", function() {
topSpinner.classList.add("closed");
});
window.addEventListener("beforeunload", function() {
topSpinner.classList.remove("closed");
});
Share
Improve this question
asked Nov 27, 2019 at 11:26
DoskiiDoskii
1461 silver badge6 bronze badges
2
- same issue here :-( – rabudde Commented Dec 19, 2019 at 13:09
- 2 I've created a fiddle for this: jsfiddle/ov6b9pdL Open this on your mobile Chrome (Android?) browser. Switch off screen for 5-10 minutes and go back to browser. In my case I can see the loading layer. – rabudde Commented Dec 19, 2019 at 13:30
4 Answers
Reset to default 6Chrome 68 (July 2018) introduced a new Page Lifecycle API: the state diagram supplied in this link does not show the System (browser) calling beforeunload
before putting the page into the frozen
state, but that is clearly what is happening.
Helpfully, the API introduced two new events that trigger as the page enters and exits this state: freeze
and resume
.
I've solved this problem on both mobile chrome and webview displays simply by adding this:
document.addEventListener('resume', (event) => {
// The page has been unfrozen: remove the spinner if it's active
topSpinner.classList.add("closed");
});
Change the load event listerner to focus
Try to persist a loader flag via localStorage
, so if the page then reloaded, check the flag again:
Pseudo code below:
$(document).ready(function() {
$('#loader').hide();
localStorage.setItem("loader", false);
window.addEventListener('beforeunload', showLoader);
});
var showLoader = function() {
var isShow = localStorage.getItem("loader");
if(!isShow){
$('#loader').show();
localStorage.setItem("loader", true);
}
};
I've logged events via Ajax to database. My tests showed, that it's not predictable which events were triggered (i.e. when using PWA). There are focus
, visibilitychange
, resize
and beforeunload
involved. I was surprised about when switching screen on with active PWA, sometimes beforeunload
is the only events that has been logged to database.
I'm using the following code now, that I've found at Kleiderliebe, which seems to work without sideeffects:
var visibilityState = 'visible';
window.addEventListener('beforeunload', function(e) {
if (visibilityState === 'visible') {
loader.show(e);
}
});
window.addEventListener('focus', loader.hide);
window.addEventListener('resize', loader.hide);
window.addEventListener('visibilitychange', function(e) {
visibilityState = document.visibilityState;
if (visibilityState === 'visible') {
loader.hide(e);
}
});