Das Ereignis 'beforeunload' wird ausgelöst, wenn die Seite unter Android im Hintergrund bleibt

8

Ich versuche, einen einfachen Ladespinner zu erstellen, der beim Navigieren auftaucht. Es wird beim Navigieren mit einem 'beforeunload'-Ereignis angezeigt und verwendet das' load'-Ereignis, um sich nach Abschluss des Vorgangs wieder auszublenden.

Das Problem ist, dass, wenn ich die Seite für einige Stunden im Hintergrund auf meinem Telefon lasse, das Ereignis "Vor dem Entladen" den Spinner auslöst und anzeigt. Wahrscheinlich, weil Chrome unter Android die Seite teilweise entlädt, um Speicherplatz zu sparen. Der Spinner verschwindet jedoch nicht von alleine und ich kann nicht herausfinden, wie ich ihn auf elegante Weise wieder verschwinden lassen kann.

Gibt es ein anderes Ereignis, das ich stattdessen verwenden sollte?

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

    window.addEventListener("beforeunload", function() {
        topSpinner.classList.remove("closed");
    });
Doskii
quelle
gleiche Ausgabe hier :-(
Rabudde
2
Ich habe dafür eine Geige erstellt: jsfiddle.net/ov6b9pdL Öffnen Sie diese in Ihrem mobilen Chrome-Browser (Android?). Schalten Sie den Bildschirm für 5-10 Minuten aus und kehren Sie zum Browser zurück. In meinem Fall kann ich die Ladeschicht sehen.
Rabudde

Antworten:

3

Chrome 68 (Juli 2018) hat eine neue Page Lifecycle-API eingeführt : Das in diesem Link bereitgestellte Statusdiagramm zeigt nicht den Systemaufruf (Browser), beforeunloadbevor die Seite in den frozenStatus versetzt wird, aber genau das passiert.

Hilfreicherweise hat die API zwei neue Ereignisse eingeführt, die ausgelöst werden, wenn die Seite diesen Status ein- und verlässt: freezeund resume.

Ich habe dieses Problem sowohl auf mobilen Chrome- als auch auf Webview-Displays gelöst, indem ich Folgendes hinzugefügt habe:

document.addEventListener('resume', (event) => {
  // The page has been unfrozen: remove the spinner if it's active
 topSpinner.classList.add("closed");
});
Mhepton
quelle
Ich sehe die Lösung aber eine Idee über die mögliche Ursache? Aus der Page Lifecycle-API geht hervor, dass es nach 'beforeUnload' möglich ist, dass es einfriert und dann wiederbelebt wird. Aber ich denke, das wäre schwer zu verfolgen / zu debuggen.
Winston Jude
0

Ändern Sie den Listener für Ladeereignisse in den Fokus

David Bradshaw
quelle
0

Ich habe Ereignisse über Ajax in der Datenbank protokolliert. Meine Tests haben gezeigt, dass es nicht vorhersehbar ist, welche Ereignisse ausgelöst wurden (dh bei Verwendung von PWA). Es gibt focus, visibilitychange, resizeund beforeunloadbeteiligt. Ich war überrascht, als ich den Bildschirm mit aktivem PWA einschaltete. Manchmal beforeunloadsind dies die einzigen Ereignisse, die in der Datenbank protokolliert wurden.

Ich verwende jetzt den folgenden Code, der ohne Nebenwirkungen zu funktionieren scheint:

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
quelle
0

Versuchen Sie, ein Loader-Flag über localStoragebeizubehalten. Wenn die Seite dann neu geladen wird, überprüfen Sie das Flag erneut:

Pseudocode unten:

$(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
quelle
Dies würde im Anwendungsfall von OP nicht helfen, da beim Einschalten des mobilen Bildschirms aus dem Standby-Modus die Seite nicht wirklich neu geladen wird.
Rabudde
Vielleicht kann es in einem solchen Fall hilfreich sein, alle x Sekunden die Funktion setTimeout zu verwenden, um den Status zu überprüfen?
Ahed Kabalan
Nicht sehr benutzerfreundlich. Stellen Sie sich eine Situation vor, in der Sie Ihren mobilen Bildschirm mit geöffnetem Browser einschalten. Das erste, was Sie sehen, ist das Loader-Symbol, das setTimeoutnach xSekunden entfernt wird. Im schlimmsten Fall müssen Sie also xSekunden warten, bis die Seite wieder angezeigt wird. Darüber hinaus ist die Verwendung eines Timers, der für diesen Sonderfall ständig läuft, nicht wirklich innovativ.
Rabudde
Nein, ich meine Timer, um den obigen Flag-Wert zu überprüfen.
Ahed Kabalan
Ich weiß nicht was du meinst. Bitte bearbeiten Sie Ihren Code, um zu zeigen, wie dies funktionieren soll.
Rabudde