LoginSignup
52
48

More than 5 years have passed since last update.

ブラウザがバックグラウンド回ったことを検知する

Last updated at Posted at 2016-08-19

Android,iOSでホームボタンなどが押されブラウザが後ろに回ったことを
検知したかった。

■対象

Android 4.0〜
iOS 7.1.2〜

■検証

・visibilitychange ... mdn Can I use
・blur
・onpagehide
・requestAnimationFrame ... mdn Can I use

visibilitychange が使える環境なら、それを優先して使う。
blur は使える環境が広いが、ブラウザメニューを開くなどの行動でも発火してしまうので、優先度は低め。

■検証結果

iOS

visibilitychange blur onpagehide
7.1.2 △※1 ×
8.4.1 ×
9.3.2 ×

※1 ... 別タブ移動は検知できるが、アプリのバックグラウンド検知は×

Android(標準ブラウザ)

visibilitychange blur onpagehide requestAnimationFrame
F-08(4.0.3) × × ×
DMO-14SH(4.0.4) × × ×
Nexus S(4.1.2) × × ×
F-07E(4.2.2) × × ×
SO-02F(4.4.2) × × ×
SO-01F(4.4.2) ?※3 ?※3 ?※3
SH-04F(5.0.2) ?※3 ?※3 ?※3
SC-04E(5.0.1) ?※3 ?※3 ?※3
SO-03F(5.0.2) △※2 △※1 × △※1
F-02G(5.0.2) △※2 △※1 × ×
SO-05F(5.0.2) △※2 △※1 × △※1
SC-01H(6.0) △※2 ?※3 ×
SO-03G(6.0) △※2 ?※3 ×
F-03H(6.0.1) ?※3 ?※3 ?※3
SO-02G(6.0.1) △※2 ?※3 ×
SO-04G(6.0.1) △※2 ?※3 ×

※1 ... 別タブ移動は検知できるが、アプリのバックグラウンド検知は×
※2 ... Page Visibility API が使える分岐に入るが、ホーム遷移で発火しない
※3 ... 安定して検知できる方法があったので、未検証

標準ブラウザがなく、 ブラウザが chromeの場合は visibilitychange が動くので
上記の表から外しました。

■まとめ

iOS 7 → onpagehide
iOS 8〜 → visibilitychange
Android は
visibilitychange が使えれば使う、(requestAnimationFrameも保険として登録)
visibilitychange が使えなければ blur で対応

Android 5.0.2 はどうしてもバックグラウンド検知ができない場合がある
(setTimeoutでアプリがバックグラウンドに回った際の処理の差で検知する方法もあるけど、端末差があったのであまり信用できない。。)

/**
 * visibilityChange判定
 */
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") {
  hidden = "hidden";
  visibilityChange = "visibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
  hidden = "webkitHidden";
  visibilityChange = "webkitvisibilitychange";
}

/**
 * バックグランド遷移判定に何を使うか
 */
var available;
if(window.navigator.userAgent.toLowerCase().indexOf('iphone os 7_0') > -1){
  // iOS7はonpagehide固定
  available = 'onpagehide';
} else if(typeof document[hidden] === "undefined"){
  if(window.requestAnimationFrame){
    available = 'requestAnimationFrame';
  } else {
    available = 'blur';
  }
} else {
  available = 'visibilityChange';
}
// 再生中にアプリがバックグラウンドにまわったか監視する
if(available === 'onpagehide'){
  window.onpagehide = function() {
    stop();
  };

} else if(available === 'blur'){
  window.addEventListener('blur', stop, false);

} else {
  observe();

  if(available === 'visibilityChange'){
    document.addEventListener(visibilityChange, stop, false);
  }
}
/*
 * requestAnimationFrameで監視
 */
var raf_id, raf_timer;
function observe(){
  raf_id = window.requestAnimationFrame(observe);
  if(raf_timer !== false){
    clearTimeout(raf_timer);
  }
  raf_timer = setTimeout(function() {
    stop();
  }, 500);
};
// バックグランド監視の停止
if(available === 'onpagehide'){
  window.onpagehide = null;
} else if(available === 'blur'){
  window.removeEventListener('blur', stop, false);
} else {

  // requestAnimationFrameの終了
  window.cancelAnimationFrame(raf_id);

  if(available === 'visibilityChange'){
    document.removeEventListener('visibilitychange', stop, false);
  }
}
52
48
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
52
48