O evento 'beforeunload' é acionado quando a página é deixada em segundo plano no Android

8

Estou tentando fazer um girador de carregamento simples que aparece ao navegar. Ele aparece usando um evento 'beforeunload' ao navegar para longe e usa o evento 'load' para se esconder novamente quando terminar.

O problema é que, quando deixo a página em segundo plano no telefone por algumas horas, o evento 'beforeunload' é acionado e exibe o botão giratório. Provavelmente porque o Chrome no Android está descarregando parcialmente a página para economizar memória. O spinner não desaparece por si só e não consigo descobrir como fazê-lo desaparecer novamente de uma maneira elegante.

Existe algum outro evento que eu deveria estar usando?

    window.addEventListener("load", function() {
        topSpinner.classList.add("closed");
    });

    window.addEventListener("beforeunload", function() {
        topSpinner.classList.remove("closed");
    });
Doskii
fonte
mesmo problema aqui :-(
rabudde 19/12/19
2
Eu criei um violino para isso: jsfiddle.net/ov6b9pdL Abra isso no navegador Chrome (Android?) Para celular. Desligue a tela por 5 a 10 minutos e volte ao navegador. No meu caso, posso ver a camada de carregamento.
Rabudde 19/12/19

Respostas:

3

O Chrome 68 (julho de 2018) introduziu uma nova API de ciclo de vida da página : o diagrama de estado fornecido neste link não mostra a chamada do sistema (navegador) beforeunloadantes de colocar a página no frozenestado, mas é claramente o que está acontecendo.

Felizmente, a API introduziu dois novos eventos que são acionados quando a página entra e sai desse estado: freezee resume.

Resolvi esse problema nos displays Chrome e WebView para dispositivos móveis simplesmente adicionando:

document.addEventListener('resume', (event) => {
  // The page has been unfrozen: remove the spinner if it's active
 topSpinner.classList.add("closed");
});
mhepton
fonte
Eu vejo a solução, mas alguma idéia sobre a possível causa? Além disso, parece que, a partir da API do ciclo de vida da página, é possível que, após o 'beforeUnload', ele congele e seja revivido. Mas acho que isso seria difícil de rastrear / depurar.
Winston Jude
0

Mude o listerner do evento de carregamento para focar

David Bradshaw
fonte
0

Registrei eventos via Ajax no banco de dados. Meus testes mostraram que não é previsível quais eventos foram acionados (por exemplo, ao usar o PWA). Há focus, visibilitychange, resizee beforeunloadenvolvidos. Fiquei surpreso ao ativar a tela com o PWA ativo, às vezes beforeunloadé o único evento registrado no banco de dados.

Estou usando o seguinte código agora, que parece funcionar sem efeitos colaterais:

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);
    }
});
rabudde
fonte
0

Tente manter um sinalizador de carregador via localStorage, portanto, se a página for recarregada, verifique o sinalizador novamente:

Pseudo código abaixo:

$(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);
  }
};
Ahed Kabalan
fonte
Isso não ajudaria no caso de uso do OP, porque ao alternar na tela do celular no modo de espera, a página não é realmente recarregada.
rabudde
Então, talvez usando a função setTimeout a cada x segundo para verificar o estado possa ser útil nesse caso?
Ahed Kabalan
Não é muito fácil de usar. Imagine uma situação em que você liga a tela do seu celular com o navegador aberto. A primeira coisa que você verá é o ícone do carregador, que será removido setTimeoutapós xsegundos, portanto, na pior das hipóteses, você terá que esperar xsegundos para ver a página novamente. Além disso, o uso de um timer que funciona o tempo todo para este caso especial não é realmente inovador.
Rabudde 25/12/19
Não, quero dizer temporizador para verificar o valor do sinalizador acima.
Ahed Kabalan
Eu não sei o que você quer dizer. Edite seu código para mostrar como isso deve funcionar.
Rabudde 26/12/19