「beforeunload」イベントは、Androidでページがバックグラウンドに置かれたときにトリガーされます


8

ナビゲート時にポップアップするシンプルな読み込みスピナーを作成しようとしています。ナビゲートするときに「beforeunload」イベントを使用して表示され、完了したら「load」イベントを使用して再び非表示にします。

問題は、ページをスマートフォンのバックグラウンドに数時間置いたままにすると、「beforeunload」イベントがトリガーされ、スピナーが表示されることです。おそらく、Android上のChromeがメモリを節約するためにページを部分的にアンロードしているためです。スピナーはそれ自体で消えることはありませんし、エレガントな方法でスピナーを再び消す方法を理解できていないようです。

代わりに使用すべき他のイベントはありますか?

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

    window.addEventListener("beforeunload", function() {
        topSpinner.classList.remove("closed");
    });

同じ問題がここにあります:-(
rabudde

2
私はこのためのフィドルを作成しました:jsfiddle.net/ov6b9pdLモバイルChrome(Android?)ブラウザーでこれを開きます。画面を5〜10分間オフにして、ブラウザに戻ります。私の場合、荷積み層を見ることができます。
rabudde

回答:


3

Chrome 68(2018年7月)は新しいPage Lifecycle APIを導入しました。このリンクで提供されている状態図beforeunloadには、ページをfrozen状態にする前のシステム(ブラウザ)呼び出しは表示されていませんが、これは明らかに起こっていることです。

便利なことに、APIは、ページがこの状態に入るときと終了するときにトリガーされる2つの新しいイベントを導入freezeしましたresume

これを追加するだけで、モバイルクロムとウェブビューの両方のディスプレイでこの問題を解決しました。

document.addEventListener('resume', (event) => {
  // The page has been unfrozen: remove the spinner if it's active
 topSpinner.classList.add("closed");
});

私は解決策を見ましたが、考えられる原因について何か考えはありますか?また、Page Lifecycle APIからは、「beforeUnload」の後でフリーズしてから復活することが可能であるように見えます。しかし、これを追跡/デバッグするのは難しいと思います。
Winston Jude


0

イベントをAjax経由でデータベースに記録しました。私のテストでは、トリガーされたイベント(つまり、PWAを使用している場合)は予測できないことがわかりました。ありfocusvisibilitychangeresizeおよびbeforeunload関与。アクティブなPWAで画面をオンに切り替えたときbeforeunload、データベースに記録された唯一のイベントである場合があることに驚きました。

現在、次のコードを使用していますが、副作用なしで動作するようです。

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

を介してローダーフラグを永続化しようとするlocalStorageため、ページがリロードされる場合は、フラグを再度確認してください。

以下の疑似コード:

$(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);
  }
};

これはOPのユースケースには役立ちません。スタンバイからモバイル画面に切り替えると、ページは実際には再ロードされないためです。
rabudde

したがって、おそらくx秒ごとにsetTimeout関数を使用して状態をチェックすることは、そのような場合に役立つでしょうか?
Ahed Kabalan

あまりユーザーフレンドリーではありません。ブラウザーを開いた状態でモバイル画面をオンにする状況を想像してみてください。最初に表示されるのはローダーアイコンです。これは秒setTimeout後に削除されるxため、最悪の場合、xページを再び表示するまで数秒待つ必要があります。さらに、この特別なケースで常に実行されているタイマーを使用することは、それほど革新的ではありません。
rabudde

いいえ、上記のフラグ値をチェックするタイマーを意味します。
Ahed Kabalan

どういう意味かわかりません。コードを編集して、これがどのように機能するかを示してください。
rabudde
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.