最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - 'beforeunload' event triggers when page is left in the background on Android - Stack Overflow

programmeradmin2浏览0评论

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
Add a ment  | 

4 Answers 4

Reset to default 6

Chrome 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);
    }
});
发布评论

评论列表(0)

  1. 暂无评论