0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

iPhoneでも全画面表示(iOS15への対応)

Last updated at Posted at 2021-09-23

はじめに

以前の投稿からの iOS15 への対応となりますので、こちらもご参照ください。
また、参考にさせていただいてるkrpanoがバージョンアップし、iOS15でのフルスクリーン表示に対応されました。

やってみるしかない

サンプルコード

index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, viewport-fit=cover" />
<style >
	:root { --sat: env(safe-area-inset-top); --sar: env(safe-area-inset-right); --sab: env(safe-area-inset-bottom); --sal: env(safe-area-inset-left); }
	* { margin:0; padding:0 }
	html, body { height:calc(100% + var(--sab)) }
	body { font-family:sans-serif; color:#fff }
	#fs { position:absolute; display:none; justify-content:center; align-items:center; width:100%; height:100%; background-color:RGBA(0,0,0,0.8) }
	#fsd { position:absolute; z-index:-2; width:100%; height:100vw; touch-action:pan-y }
	#container { position:fixed; z-index:1; width:100%; height:100%; background-color:#b1dff7; touch-action:none; transform:translateZ(0) }
	#container p { position:absolute; width:40px; height:40px; background-color:#fff }
	#container p:nth-child(1) { left:5px; top:5px; margin-left:var(--sal) }
	#container p:nth-child(2) { top:5px; right:5px; margin-right:var(--sar) }
	#container p:nth-child(3) { right:5px; bottom:5px; margin-right:var(--sar); margin-bottom:var(--sab) }
	#container p:nth-child(4) { bottom:5px; left:5px; margin-bottom:var(--sab); margin-left:var(--sal) }
	@media ( orientation:landscape ){
		#container p:nth-child(n+3) { margin-bottom:0 }
	}
</style>
</head>
<body>
    <div id="container">
        <p></p>
        <p></p>
        <p></p>
        <p></p>
    </div>
    <script>
        let _ua = navigator.userAgent.toLowerCase(),
            _container = document.querySelector('#container');

        if ( (/iphone/.test(_ua)) && !(/crios|edgios/.test(_ua)) ){
            var _fs = document.createElement('div'),
                _fsd = document.createElement('div');
            _fs.id = 'fs';
            _fs.innerHTML = '&#8593;&nbsp;SWIPE';
            _container.appendChild(_fs);
            _fsd.id = 'fsd';
            document.body.insertBefore(_fsd, _container);

            document.addEventListener( 'DOMContentLoaded', fs_display );
            window.addEventListener( 'resize', fs_display );

            function fs_display() {
                if ( window.orientation == 0 ) {
                    _container.style.height = '100%';
                    _fs.style.display = 'none';
                } else {
                    _container.style.height = '100vh';
                    if ( screen.width - window.innerHeight <= 20 ) {
                        _fs.style.display = 'none';
                        _fsd.style.zIndex = '-2';
                    } else if ( screen.width - window.innerHeight > 20 ) {
                        _fs.style.display = 'flex';
                        _fsd.style.zIndex = '2';
                        window.scrollTo(0, 0);
                    }
                }
            }
        }
    </script>
</body>
</html>

> 構造(変更箇所)
HTML
<body>
    <div id="fsd"></div>
    <div id="container">
        // Your contents.
        <div id="fs">&#8593;&nbsp;SWIPE</div>
    </div>
</body>

↑ SWIPEを表示するdiv#fsdiv#container内に、スワイプする為の空要素としてdiv#fsddiv#container外に分けた構造とします。

CSS
html, body { height:calc(100% + env(safe-area-inset-bottom)) }
#fs { position:absolute; display:none; justify-content:center; align-items:center; width:100%; height:100%; background-color:RGBA(0,0,0,0.8) }
#fsd { position:absolute; z-index:-2; width:100%; height:100vw; touch-action:pan-y }
#container { position:fixed; z-index:1; width:100%; height:100%; background-color:#b1dff7; touch-action:none; transform:translateZ(0) }

div#containerposition:fixedとし、html,bodyにはheight:calc(100% + env(safe-area-inset-bottom))div#fsdheight:100vwを設定します。
div#fsdtouch-action:pan-ydiv#contanertouch-action:noneとし制限をかけるのは変わりません。

div#fsdheight:100vwとすることで、portrait時には邪魔にならずlandscape時にはスワイプする為の要素となります。

div#containertransform:translateZ(0)を設定することで、position:fixedでも非表示領域をレンダリングしてくれます。

設定からの文字サイズ変更には対応しておりますが、ブラウザ側での文字サイズ変更には対応しておりません。


> 制御(変更箇所)
JS
let _ua = navigator.userAgent.toLowerCase(),
	_container = document.querySelector('#container');

if ( (/iphone/.test(_ua)) && !(/crios|edgios/.test(_ua)) ){
	var _fs = document.createElement('div'),
+		_fsd = document.createElement('div');
	_fs.id = 'fs';
	_fs.innerHTML = '&#8593;&nbsp;SWIPE';
	_container.appendChild(_fs);
+	_fsd.id = 'fsd';
+	document.body.insertBefore(_fsd, _container);

	document.addEventListener( 'DOMContentLoaded', fs_display );
	window.addEventListener( 'resize', fs_display );

	function fs_display() {
		if ( window.orientation == 0 ) {
+			_container.style.height = '100%';
			_fs.style.display = 'none';
		} else {
+			_container.style.height = '100vh';
			if ( screen.width - window.innerHeight <= 20 ) {
				_fs.style.display = 'none';
+				_fsd.style.zIndex = '-2';
			} else if ( screen.width - window.innerHeight > 20 ) {
				_fs.style.display = 'flex';
+				_fsd.style.zIndex = '2';
+				window.scrollTo(0, 0);
			}
		}
	}
}

div#containerはportrait時height:100%、landscape時height:100vhとなるよう制御し、div#fsdの表示・非表示をz-indexで制御しコンテンツの高さを保つことで上部バーの再表示を防ぎます。

window.scrollTo(0, 0)でスクロール状態をリセットすることで、上方向スワイプのみの操作でバーを隠せるようになりました。

まとめ

下部セーフエリア周りの仕様が、、safe-area-inset-bottomのサイズと実際のタップ範囲が違う、、のか、、ツールバーのサイズは1rem + env(safe-area-inset-bottom) ということらしく、タップ範囲となるっぽいのだが、、下のタブバー表示でツールバー非表示にするとタップ範囲は併せて狭くなってくれるの、、、だが、上部アドレスバー表示の時は変わらない、、、んだ。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?