[HTML5] フルスクリーンの開始と解除

例えば写真などを出来る限り広い画面で、余計な情報を取り払って表示したい場合があります。ゲームなどではよくある要件だと思います。今回はそんなときに利用する「フルスクリーン化」を取り上げます。

HTML5でフルスクリーン

ブラウザの対応状況

正直なところ鬼門ですw 執筆時点(2019/08)では多くのブラウザが完全に対応していないため、本番で利用するには処理の場合分けが必要になります。詳しくはCan I useを参照してください。PCではフルスクリーンにするだけであれば基本的に実現できます。しかしiPhoneでは利用できないのは痛いところですね…。

PC

ブラウザ 対応状況 バージョン 備考
IE 🔺 11.0〜 (2013/10〜) Promise非対応
Edge 🔺 12〜 (2015/06〜) Promise非対応
GoogleChrome 71〜 (2018/12〜)
FireFox 64〜 (2018/12〜)
Safari 🔺 6〜 (2012/06〜) ::backdrop非対応。:full-screen非対応に変わり:fullscreen対応。Promise非対応

スマホ

ブラウザ 対応状況 バージョン 備考
Safari(iPhone) - 非対応
Safari(iPad) 🔺 12.1〜 (2018/09〜) 無効化できないボタンを前面に表示
Android Browser - 非対応
Chrome 🔺 75〜 (2019/06〜) ::backdrop非対応。:full-screen非対応に変わり:fullscreen対応。Promise非対応
FireFox(Android) 67〜 (2019/05〜)
  • 2019年8月7日時点での情報です。
  • 実際に利用する際には最新の情報をご確認ください。

サンプル

実際に以下のサンプルから試すことができます。 miku3.net

  • 画像の左上にあるボタンをクリック(タップ)すると、画像だけをフルスクリーン表示にします。
  • フルスクリーン状態で左上にあるボタンをクリック(タップ)すると元に戻ります。
  • フルスクリーンに非対応のブラウザで実行した場合は、アラートが表示されます。

ソースコード

以下のページを参考にさせていただきました。 https://developers.google.com/web/fundamentals/native-hardware/fullscreen/?hl=jadevelopers.google.com

CSSは外部ファイルにしています。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>HTML5 フルスクリーン</title>
  <link rel="stylesheet" href="style.css" type="text/css" media="all">
</head>
<body>

<h1>アルバム</h1>
アイコン「<img src="icon/compress-solid.svg" width="16" height="16">」をクリック(タップ)するとフルスクリーン表示になります。

<div id="album">
  <img src="image/1udon.jpg" id="photo" width="100%" alt="一本うどん">
  <img src="icon/compress-solid.svg" id="btn-open" class="btn" width="64" height="64" style="display:block">
  <img src="icon/compress-arrows-alt-solid.svg" id="btn-close" class="btn" width="64" height="64">
</div>


<script>
const btnOpen  = document.querySelector("#btn-open");   // フルスクリーン化ボタン
const btnClose = document.querySelector("#btn-close");  // フルスクリーンキャンセルボタン

window.onload = ()=>{
  const album = document.querySelector("#album");      // フルスクリーンにするオブジェクト

  //--------------------------------
  // [event] 開始ボタンをクリック
  //--------------------------------
  btnOpen.addEventListener("click", ()=>{
    if( ! enabledFullScreen() ){
      alert("フルスクリーンに対応していません");
      return(false);
    }
    // フルスクリーンを開始
    goFullScreen(album);
  });

  //--------------------------------
  // [event] 閉じるボタンをクリック
  //--------------------------------
  btnClose.addEventListener("click", ()=>{
    // フルスクリーンを解除
    cancelFullScreen(album);
  });

  //--------------------------------
  // フルスクリーンイベント
  //--------------------------------
  eventFullScreen( ()=>{
      // ボタンを入れ替える
    if( getFullScreenObject() ){
      console.log("フルスクリーン開始");
      btnOpen.style.display  = "none";    // OpenをOFF
      btnClose.style.display = "block";   // CloseをON
    }
    else{
      console.log("フルスクリーン終了");
      btnClose.style.display = "none";    // CloseをOFF
      btnOpen.style.display  = "block";   // OpenをON
    }
  });
};

/**
 * フルスクリーン開始/終了時のイベント設定
 *
 * @param {function} callback
 */
function eventFullScreen(callback){
  document.addEventListener("fullscreenchange", callback, false);
  document.addEventListener("webkitfullscreenchange", callback, false);
  document.addEventListener("mozfullscreenchange", callback, false);
  document.addEventListener("MSFullscreenChange", callback, false);
}

/**
 * フルスクリーンが利用できるか
 *
 * @return {boolean}
 */
function enabledFullScreen(){
  return(
    document.fullscreenEnabled || document.mozFullScreenEnabled || document.documentElement.webkitRequestFullScreen || document.msFullscreenEnabled
  );
}

/**
 * フルスクリーンにする
 *
 * @param {object} [element]
 */
function goFullScreen(element=null){
  const doc = window.document;
  const docEl = (element === null)?  doc.documentElement:element;
  let requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
  requestFullScreen.call(docEl);
}

/**
 * フルスクリーンをやめる
 */
function cancelFullScreen(){
  const doc = window.document;
  const cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen;
  cancelFullScreen.call(doc);
}

/**
 * フルスクリーン中のオブジェクトを返却
 */
function getFullScreenObject(){
  const doc = window.document;
  const objFullScreen = doc.fullscreenElement || doc.mozFullScreenElement || doc.webkitFullscreenElement || doc.msFullscreenElement;
  return(objFullScreen);
}
</script>
</body>
</html>

解説

フルスクリーンが利用できるか調べる

HTML5標準ではdocument.fullscreenEnabledを見ればよいのですが、ブラウザによってはこれだと動きません。 FireFoxはdocument.mozFullScreenEnabled、Chrome,Safari,Operaはdocument.documentElement.webkitRequestFullScreenなど合計3種類を見比べることになります。

function enabledFullScreen(){
  return(
    document.fullscreenEnabled || document.mozFullScreenEnabled || document.documentElement.webkitRequestFullScreen || document.msFullscreenEnabled
  );
}

フルスクリーンにする

これもHTML5標準ではelement.requestFullscreen()を呼ぶだけなんですが、同様にブラウザによって接頭詞を付ける必要があります。 FireFoxはmozRequestFullScreen()、Chrome,Safari,OperaはwebkitRequestFullScreen()、IE11ではmsRequestFullscreen()となります。

let requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
requestFullScreen.call(docEl);

フルスクリーンを解除する

もうわかったよって感じですが、こちらも同様ですw HTML5標準ではexitFullscreen()、FireFoxはmozCancelFullScreen()、Chrome,Safari,OperaはwebkitExitFullscreen()、IE11ではmsExitFullscreen()を実行します。

const cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen;
cancelFullScreen.call(doc);

フルスクリーン開始/解除時のイベント

フルスクリーンが開始されたときと、解除されたときのイベントはfullscreenchangeで取得することができます。今回のサンプルではボタンが押されたタイミングで処理を行っていますが、これ以外にも例えばESCキーを押した場合などブラウザが提供する機能でフルスクリーンを解除されることがあります。このイベントを補足する必要がある場合にはaddEventListenerにイベント処理を登録しておきます。

function eventFullScreen(callback){
  document.addEventListener("fullscreenchange", callback, false);
  document.addEventListener("webkitfullscreenchange", callback, false);
  document.addEventListener("mozfullscreenchange", callback, false);
  document.addEventListener("MSFullscreenChange", callback, false);
}

fullscreenchangeは開始時と終了時も同様に呼ばれますので、登録する処理の中でどちらか判定する必要が出てきます。何か分かりやすいプロパティでもあれば良いのですがそれらしき物が無いようなので、ここではwindow.document.fullscreenElementを参照しフルスクリーン化された要素(オブジェクト)を取得する方法を取っています。

フルスクリーン化された状態でwindow.document.fullscreenElementを参照するとフルスクリーン状態になっている要素を、フルスクリーンが解除されていればundefinedが返って来るのを利用しています。

// クロスブラウザを考慮しない場合はこんな感じ
document.addEventListener("fullscreenchange", ()=>{
  if( window.document.fullscreenElement ){
    console.log("フルスクリーン開始");
  }
  else{
    console.log("フルスクリーン終了");
  }
});

ライブラリを利用する

今回はスクラッチで書きましたが、対応状況が変化する度に修正するのも面倒ですので(そして大抵の場合忘れる)、メンテナンスがされているライブラリを利用するのがおすすめです。

screenfull.js

フルスクリーン業界(どこだw)ではよく耳にするscreenfull.jsが鉄板でしょうか。 github.com

非常に簡潔に記述できます。

<script src="screenfull.min.js">
<script>
  // フルスクリーンにする
  document.querySelector("#btn-open").addEventListener("click", ()=>{
    if ( screenfull.enabled ) {
      const element = document.querySelector("#photo");
      screenfull.request(element);
    }
    else{
      alert("フルスクリーン未対応です");
    }
  });

  // フルスクリーンを解除
  document.querySelector("#btn-close").addEventListener("click", ()=>{
    screenfull.exit();
  });
</script>

インストールはGitHubからダウンロードするか、CDNにアップされている物も利用可能です。もちろんnpm等で入れることもできます。

$ npm install screenfull

iPhone/Androidでもフルスクリーンにしたい

metaタグ編

特にiPhoneはフルスクリーンが非対応のため通常はできないわけですが、ユーザーが特定の操作を行うことで、それっぽいことが可能になります。

まず対象のページのheadタグ内に以下のmetaタグを記述します。viewportの方は適宜指定してください。

<head>
  <meta name="viewport" content="initial-scale=1.0">

  <!-- iOS/Safari用 -->
  <meta name="apple-mobile-web-app-capable" content="yes">

  <!-- Android/Chrome用 -->
  <meta name="mobile-web-app-capable" content="yes">

このページをブラウザで表示し、メニューからデスクトップにアイコンを追加します。

追加されたアイコンをタップします。

ご覧の通りURLなどが表示されるバーが消え去り、全ての画面をブラウザの表示領域として利用できるようになります。

スクショはiOSですが、Androidでも同様です。

manifest編

詳細は割愛しますが、manifestファイルを用意することで、metaタグで指定するよりもより細かく指定を行うことができます。

HTMLからはlinkタグでmanifestファイルの場所を指定します。

<link rel="manifest" href="/manifest.json">

manifestファイルの中身は単なるJSONです。

{
  "short_name": "Kinlan's Amaze App",
  "name": "Kinlan's Amazing Application ++",
  "icons": [
    {
      "src": "launcher-icon-4x.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ],
  "start_url": "/index.html",
  "display": "standalone",
  "orientation": "landscape"
}
  • サンプルはこちらから引用させていただきました。
  • 各ブラウザの対応状況はCan I useを参照ください。

素材

アイコンはFontAwesomeを利用しています。

参考ページ