LoginSignup
59
62

More than 5 years have passed since last update.

[iOS/Android]ブラウザでページが非表示になったことを検知する方法

Last updated at Posted at 2016-07-19

やりたいこと

webページが非表示になったことを検知して、処理を行いたい

検証

検証環境

  • iOS : iPhone6 (9.3.1)
  • Android : Xperia501SO (5.1.1)
  • Proxy : BurpSuite (1.6.32)

検証内容(その1)

beforeunload / pagehide / unloadイベントを仕込んでやってみた

検証結果(その1)

[iOS]

動作 発生イベント
ページリロード pagehide
unload
リンクタップ pagehide
unload
リンクタップ(target blunk) -
ブラウザバック pagehide
unload
電源ボタンタップ -
ホームボタン -
ホームボタン(ダブルタップ) -

[Android]

動作 発生イベント
ページリロード beforeunload
pagehide
unload
リンクタップ beforeunload
pagehide
unload
リンクタップ(target blunk) -
ブラウザバック beforeunload
pagehide
unload
電源ボタンタップ -
ホームボタン -
アプリ履歴ボタンタップ -

考察(その1)

結果からわかる通り、デバイスに備わっているボタンをタップした時のイベントが拾えていない
iOSは、beforeunloadが呼ばれないみたい

検証内容(その2)

次に、Page Visibility APIを仕込んでやってみた

検証結果(その2)

[iOS]

動作 発生イベント
ページリロード -
リンクタップ -
リンクタップ(target blunk) -
ブラウザバック -
電源ボタンタップ visibilityChange
ホームボタン visibilityChange
ホームボタン(ダブルタップ) -
ホームボタン(ダブルタップ)→電源ボタン visibilityChange

[Android]

動作 発生イベント
ページリロード -
リンクタップ -
リンクタップ(target blunk) visibilityChange
ブラウザバック -
電源ボタンタップ visibilityChange
ホームボタン visibilityChange
アプリ履歴ボタンタップ visibilityChange

考察(その2)

各種デバイスのボタンイベント後に、visibilityChangeイベントが呼ばれページが非表示になったことは検知できた
ただし、どの動作が行われたかは、検知できないみたい
iOSの場合、ホームボタンのダブルタップでは、visibilityChangeイベントが呼ばれず、その後、電源ボタンを押してみたところ、visibilityChangeイベントが呼ばれた

結果まとめ

以上の検証結果からbeforeunload / pagehide / unloadイベントとPage Visibility APIを組み合わせるとページが非表示になる動作を大体捉えられることがわかった

ページ遷移系のイベントは、とりあえず、pagehideunloadを読んでおけば大丈夫
iOS8とかAndroid 4/6系でどう動くかは、確認していないので、そのうち確認する予定

サンプルコード

sample.js
// デバイスのボタンイベントを検知するためのリスナー
function setVisibilityEvent(){
  var hidden, visibilityChange;
  if (typeof document.hidden !== "undefined") {
    hidden = "hidden";
    visibilityChange = "visibilitychange";
  } else if (typeof document.mozHidden !== "undefined") {
    hidden = "mozHidden";
    visibilityChange = "mozvisibilitychange";
  } else if (typeof document.msHidden !== "undefined") {
    hidden = "msHidden";
    visibilityChange = "msvisibilitychange";
  } else if (typeof document.webkitHidden !== "undefined") {
    hidden = "webkitHidden";
    visibilityChange = "webkitvisibilitychange";
  }
  document.addEventListener(visibilityChange, function(){
    // ページ非表示と表示時に呼ばれるため、表示から非表示になった時だけ呼ばれるように
    // document.hidden条件を追加
    if(document.hidden){
      request("visibilitychange");
    }
  }, false);
}

// ページ遷移イベントを検知するためのリスナー
function setPageTransitionListener(){
  window.addEventListener("pagehide", function(){
    request("pagehide");
  }, false);
}

// 非表示時の処理
// 以下の場合、サーバに通知する処理
function request(event){
  var id = 'test_'+window.btoa(event);
  var img = document.createElement('img');
  var endPoint = 'http://...';
  img.src = endPoint + query;
  img.id = id;
  body.appendChild(img);
  img.parentNode.removeChild(img);
}

function main(){
  setVisibilityEvent();
  setPageTransitionListener();
}

main();
59
62
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
59
62