phantom4

[js] スマートフォンのアドレスバーを、コンテンツの高さが足りないときでも非表示にする

——————————–
2013/4/24 追記
改良版を作成しました。

——————————–
アドレスバーの非表示を、要素の高さが足りないときでもできるように試してみました。
xperia arcとiPhoneで確認。

(function () {

	/**
	 * スマートフォンのアドレスバーを非表示にする
	 *
	 * @author ngi@phantom4.org
	 */
	function hideAddressBar () {
		document.body.style.height = "3000px";	//ダミーの高さを設定
		document.body.style.minHeight = "";

		setTimeout(function () {
			window.scrollTo(0, 1);	//アドレスバーを隠す

			setTimeout(function () {
				//bodyの最低サイズを設定
				document.body.style.minHeight = window.innerHeight + document.body.scrollTop + "px";
				document.body.style.height = "auto";	//高さを戻す
			}, 500);
		}, 100);
	}

	if(window.addEventListener && navigator.userAgent.match(/iphone|ipod|android/i)) {
		window.addEventListener("load", hideAddressBar);
		window.addEventListener("orientationchange", hideAddressBar);
	}
}());

圧縮したソースはこちら

(function(){function a(){document.body.style.height="3000px";document.body.style.minHeight="";setTimeout(function(){window.scrollTo(0,1);setTimeout(function(){document.body.style.minHeight=window.innerHeight+document.body.scrollTop+"px";document.body.style.height="auto"},500)},100)}if(window.addEventListener&&navigator.userAgent.match(/iphone|ipod|android/i)){window.addEventListener("load",a);window.addEventListener("orientationchange",a)}}());

デモ

デモ(別ウィンドウで開きます)

ソース

hide_address_bar.js
hide_address_bar.min.js(圧縮版)

body.style.height&body.style.minHeightを強制的に設定してしまうので、既存のcssで設定している場合は注意。

処理内容を簡単に説明しておくと
1. body.style.heightにダミーの高さを設定する
2. window.scrollTo(0, 1);でアドレスバーを非表示
3. body.style.minHeightにアドレスバー非表示後の高さを設定

window.outerHeight – window.innerHeightで計算する方法も検討しましたが、outerHeightは画面の倍率の影響を受けないのに対して、window.innerHeightは画面の倍率の影響を受けることが分かり、倍率が1以外では使えなかったため断念しました。

——————————–
2012/3/29 追記
ページに画像をたくさん使っているときなどに上記の方法だとうまく処理されないときがあり(onloadが無視される?)、リトライするように仕様変更してみました。
また、body.style.heightを設定しないように変更しました。(body.style.minHeightのみ設定)
うまくいくかどうかは未検証。

——————————–
2012/10/12 追記
Androidでzoomを制御して画面サイズに合わせる作り方をすることが多くなり、その場合に高さがおかしくなっていたので対応。

——————————–
2012/10/25 追記
initial-scale=1以外のときに問題あったので暫定で対応。

——————————–
2012/12/16 追記
zoomを変更するような作りの場合に、対応できない場合があったので修正。
ただし、zoomを制御するタイミングによっては下記のスクリプトをカスタマイズする必要がありそう。
あと、アドレスバーを消したタイミングで、グローバル変数のhideAddressBarCompleteをカウントする仕様を追加。(ここはできれば変えたい)

/**
 * スマートフォンのアドレスバーを非表示
 *
 * @author ngi@phantom4.org
 */
(function () {
	var
		RETRY_INTERVAL = 500,

		defaultInnerHeight,
		timer = 0;

	/**
	 * スマートフォンのアドレスバーを非表示にする
	 *
	 */
	function hideAddressBar() {
		defaultInnerHeight = window.outerHeight;
		document.body.style.minHeight = String(3000 * (1 / getZoom())) + "px";	//ダミーの高さを設定

		setTimeout(function () {
			setBodyHeight();
			if(timer) {
				clearInterval(timer);
			}
			timer = setInterval(setBodyHeight, RETRY_INTERVAL);
		}, 100);	//zoomを制御する作り方の場合、ここの数字を大きくしてみてください(1000とか)
	}

	/**
	 * アドレスバーの非表示
	 *
	 */
	function setBodyHeight() {
		if(document.body.scrollTop <= 0) {
			window.scrollTo(0, 1);	//アドレスバーを隠す
		}

		setTimeout(function () {
			var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
			if(scrollTop > 0) {
				document.body.style.minHeight = window.innerHeight * (1 / getZoom()) + "px";
				clearInterval(timer);
				timer = null;
				window.hideAddressBarComplete++;	//グローバル変数に変更を保持
			}
		}, 0);
	}

	/**
	 * htmlのzoomの値を取得
	 *
	 * @return {int} zoomの値
	 */
	function getZoom() {
		return document.defaultView.getComputedStyle(document.getElementsByTagName("html")[0], "").zoom || 1;
	}

	if(window.addEventListener && navigator.userAgent.match(/iphone|ipod|android/i)) {
		window.hideAddressBarComplete = 0;
		window.addEventListener("load", hideAddressBar);
		window.addEventListener("orientationchange", hideAddressBar);
	}
}());

デモ

デモ(別ウィンドウで開きます)

ソース

hide_address_bar2.js
hide_address_bar2.min.js(圧縮版)

モバイルバージョンを終了