(これは複数の部分からなる質問です。シナリオを要約するために最善を尽くします。)
私たちは現在、ユーザーがタブ付きコンテンツ間をスワイプし、各タブ付きコンテンツ内を垂直方向にスクロールできるようにするレスポンシブWebアプリケーション(ニュースリーダー)を構築しています。
この問題を解決する一般的な方法は、ブラウザのビューポートを埋めるラッパーdiv
を作成し、overflow
をhidden
またはauto
に設定してから、水平方向および/または垂直方向にスクロールすることです。
このアプローチは素晴らしいですが、1つの主な欠点があります:ドキュメントの高さはブラウザのビューポートとまったく同じなので、モバイルブラウザはアドレスバー/ナビゲーションメニューを隠しません。
より多くのスクリーンスペースを得ることを可能にする 数多くのハックとビューポートプロパティ がありますが、minimal-ui
(iOS 7.1で導入された)と同じくらい効果的なものはありません。
IOS 8 beta4がMobile Safariからminimal-ui
を削除したというニュース(昨日の iOS 8リリースノート のWebkitのセクションを参照)が、私たちに疑問を残しました。
Q1。それでもMobile Safariのアドレスバーを隠すことはできますか?
私たちが知る限り、iOS 7 はwindow.scrollTo
ハックに応答しなくなりました 。垂直レイアウトまたはmobile-web-app-capable
を使用してください。
Q2。それでも、同様のソフトフルスクリーン体験をすることは可能ですか?
ソフトフルスクリーンによると、mobile-web-app-capable
メタタグを使わずにすみます。
当社のWebアプリはアクセスしやすいように構築されており、どのページもネイティブのブラウザメニューを使用してブックマークまたは共有できます。 mobile-web-app-capable
を追加することで、ユーザーがそのようなメニューを起動できないようにして(ホームスクリーンに保存されているとき)、ユーザーを混乱させ、嫌いになります。
minimal-ui
は以前は中道でしたが、デフォルトではメニューを非表示にしていましたが、 タップするとアクセスできるようになりました 。ユーザー補助の問題(ユーザーがメニューをアクティブにするためにタップする場所を知らないなど)。
Q3。フルスクリーンエクスペリエンスは問題を解決する価値がありますか?
フルスクリーンAPI はすぐにはiOSには届かないようですが、たとえそうであっても、メニューがどのように保持されるのかわかりません。アクセス可能(Android上のChromeでも同じ)。
この場合は、モバイルサファリをそのままにして、ビューポートの高さを考慮する必要があります(iPhone 5+の場合は460 = 568 - 108、OSバー、アドレスバー、ナビゲーションメニューは108です。iPhone4またはそれ以上は372です。
(ネイティブアプリの作成以外に)いくつかの代替手段を聞きたいです。
IOS 8では、minimal-uiビューポートプロパティは サポートされなくなりました です。ただし、minimal-ui自体はなくなっていません。ユーザーは「タッチドラッグダウン」ジェスチャーで最小UIを入力できます。
ビューステートを管理するには、いくつかの前提条件と障害があります。 minimal-uiが機能するには、ユーザーがスクロールできるように十分なコンテンツが必要です。 minimal-uiを持続させるには、ウィンドウのスクロールはページのロード時および方向の変更後にオフセットする必要があります。ただし、screen
変数を使用して minimal-uiの次元を計算する方法はありません _、したがって、ユーザーが事前にminimal-uiにいることを知らせる方法はありません。
これらの所見は、iOS 8の場合はBrim - view managerの開発の一環として行われた調査の結果です。最後の実装は次のように機能します。
ページが読み込まれると、Brimはトレッドミル要素を作成します。 Treadmill要素は、スクロールするユーザースペースを確保するために使用されます。トレッドミル要素が存在することで、ユーザーはミニマムUIビューに入ることができ、ユーザーがページをリロードしたりデバイスの向きを変更したりしても引き続き表示されます。ずっとユーザーには見えません。この要素のIDは
brim-treadmill
です。ページのロード時または向きの変更後、Brimは Scream を使用して、ページが最小UIビューに表示されているかどうかを検出します(以前に最小UIに表示され、再ロードされたページは最小のままです)コンテンツの高さがビューポートの高さより大きい場合は-ui。
Pageがminimal-uiの場合、Brimは文書のスクロールを無効にします(これは、メイン要素の内容に影響しない 安全な方法 で行われます)。文書のスクロールを無効にすると、上方向にスクロールしたときに誤って最小UI文字を残してしまうのを防ぐことができます。元のiOS 7.1の仕様によると、一番上のバーをタップすると残りのクロムが元に戻ります。
最終結果は次のようになります。
ドキュメンテーションのために、そしてあなたがあなた自身の実装を書くことを好む場合には、デバイスが orientationchange の直後に最小UIにあるかどうかを検出するために Scream を使うことはできません。 _ eventは、回転アニメーションが終了するまでwindow
の寸法が新しい方向を反映しないためです。リスナーを orientationchangeend イベントにアタッチする必要があります。
Scream と orientationchangeend は、このプロジェクトの一環として開発されました。
minimal-ui
を模倣するためのプログラム的な方法がないので、私達は私達の利点にcalc()
および既知のiOSアドレスバーの高さを使用して異なる回避策を考え出しました:
次のデモページ( ではGistから入手できます。技術的な詳細 )では、ユーザーにスクロールを促し、ソフトフルスクリーンを表示します(アドレスバーを隠す)。ヘッダーとコンテンツが新しいビューポートに表示されます。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Scroll Test</title>
<style>
html, body {
height: 100%;
}
html {
background-color: red;
}
body {
background-color: blue;
margin: 0;
}
div.header {
width: 100%;
height: 40px;
background-color: green;
overflow: hidden;
}
div.content {
height: 100%;
height: calc(100% - 40px);
width: 100%;
background-color: purple;
overflow: hidden;
}
div.cover {
position: absolute;
top: 0;
left: 0;
z-index: 100;
width: 100%;
height: 100%;
overflow: hidden;
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
display: none;
}
@media screen and (width: 320px) {
html {
height: calc(100% + 72px);
}
div.cover {
display: block;
}
}
</style>
<script>
var timeout;
window.addEventListener('scroll', function(ev) {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
if (window.scrollY > 0) {
var cover = document.querySelector('div.cover');
cover.style.display = 'none';
}
}, 200);
});
</script>
</head>
<body>
<div class="header">
<p>header</p>
</div>
<div class="content">
<p>content</p>
</div>
<div class="cover">
<p>scroll to soft fullscreen</p>
</div>
</body>
</html>
minimal-ui
は役に立つものでも有害なものでもありえます。そして、より新しい、より大きなiPhoneに有利になるように、今やトレードオフには別のバランスがあると思います。
私はHTML5アプリのための私のjsフレームワークを使っている間、私は問題に対処していました。それぞれに欠点がある多くの解決策を試みた後、私は6より前のiPhoneで失われたスペースを考慮することを諦めました。状況を考えると、私は唯一の強固で予測可能な振る舞いがあらかじめ決められたものだと思います。
一言で言えば、私は結局どんな形のminimal-uiも防ぐことになったので、少なくとも私のスクリーンの高さは常に同じで、あなたはあなたがあなたのアプリケーションのための実際のスペースを常に知っている。
時間の助けを借りて、十分なユーザーがより多くのスペースを持つことになります。
編集
これはデモ目的では少し単純化されていますが、うまくいくはずです。メインコンテナがあるとします
html, body, #main {
height: 100%;
width: 100%;
overflow: hidden;
}
.view {
width: 100%;
height: 100%;
overflow: scroll;
}
その後:
それからjsで、私は#main
の高さをウィンドウの利用可能な高さに設定します。これはまた、iOSとAndroidの両方に見られる他のスクロールバグに対処するのに役立ちます。それはまたそれを更新する方法について対処する必要があることを意味します。
スクロールの境界に達すると、私は過剰スクロールをブロックします。これは私のコードではもう少し深くなっていますが、基本的な機能については この答え の原則に従うこともできると思います。私はそれが少しちらつくことができると思います、しかし仕事をします。
補足として:このアプリもハッシュ化されたアドレスへの内部ルーティングを使用しているのでブックマーク可能ですが、私は自宅に追加するためのプロンプトiOSユーザーも追加しました。私はこのようにして忠誠心と訪問客を元に戻すのを助けます(そして失われたスペースは戻ってきました)。
私がこれを直すために見つけた最も簡単な方法はユーザーエージェントがiphoneであったどんな要求に対してもbodyとhtml要素の高さを100.1%に設定することでした。これはランドスケープモードでのみ動作しますが、必要なことはそれだけです。
html.iphone,
html.iphone body { height: 100.1%; }
https://www.360jungle.com/virtual-tour/25 でそれをチェックしてください。
ここでの根本的な問題は、コンテンツがビューポートと同じかそれより小さい場合、iOS8 safariはスクロールダウン時にアドレスバーを隠さないことです。
すでにご存知のとおり、一番下にパディングを追加すると、この問題を回避できます。
html {
/* enough space to scroll up to get fullscreen on iOS8 */
padding-bottom: 80px;
}
// sort of emulate safari's "bounce back to top" scroll
window.addEventListener('scroll', function(ev) {
// avoids scrolling when the focused element is e.g. an input
if (
!document.activeElement
|| document.activeElement === document.body
) {
document.body.scrollIntoViewIfNeeded(true);
}
});
たとえばUAがgt-ios8
クラスを<html>
に追加することで、上記のcssを条件付きで適用する必要があります。
以下の例のようなものを使用して、( https://Gist.github.com/bitinn/1700068a276fb29740a7 の作業の助けを借りてまとめることができますIS )それはiOS 11ではあまりうまくいきませんでした:
これがiOS 11.03で動作する修正されたコードです、それがあなたのために働いたかどうかコメントしてください。
ブラウザがスクロールできるようにBODYにサイズを追加することが重要です。 身長:計算値(100%+ 40ピクセル)。
下のフルサンプルとブラウザで表示するためのリンク(テストしてください)
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CodeHots iOS WebApp Minimal UI via Scroll Test</title>
<style>
html, body {
height: 100%;
}
html {
background-color: red;
}
body {
background-color: blue;
/* important to allow page to scroll */
height: calc(100% + 40px);
margin: 0;
}
div.header {
width: 100%;
height: 40px;
background-color: green;
overflow: hidden;
}
div.content {
height: 100%;
height: calc(100% - 40px);
width: 100%;
background-color: purple;
overflow: hidden;
}
div.cover {
position: absolute;
top: 0;
left: 0;
z-index: 100;
width: 100%;
height: 100%;
overflow: hidden;
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
display: none;
}
@media screen and (width: 320px) {
html {
height: calc(100% + 72px);
}
div.cover {
display: block;
}
}
</style>
<script>
var timeout;
function interceptTouchMove(){
// and disable the touchmove features
window.addEventListener("touchmove", (event)=>{
if (!event.target.classList.contains('scrollable')) {
// no more scrolling
event.preventDefault();
}
}, false);
}
function scrollDetect(event){
// wait for the result to settle
if( timeout ) clearTimeout(timeout);
timeout = setTimeout(function() {
console.log( 'scrolled up detected..' );
if (window.scrollY > 35) {
console.log( ' .. moved up enough to go into minimal UI mode. cover off and locking touchmove!');
// hide the fixed scroll-cover
var cover = document.querySelector('div.cover');
cover.style.display = 'none';
// Push back down to designated start-point. (as it sometimes overscrolls (this is jQuery implementation I used))
window.scrollY = 40;
// and disable the touchmove features
interceptTouchMove();
// turn off scroll checker
window.removeEventListener('scroll', scrollDetect );
}
}, 200);
}
// listen to scroll to know when in minimal-ui mode.
window.addEventListener('scroll', scrollDetect, false );
</script>
</head>
<body>
<div class="header">
<p>header zone</p>
</div>
<div class="content">
<p>content</p>
</div>
<div class="cover">
<p>scroll to soft fullscreen</p>
</div>
</body>
ここに完全な例のリンク: https://repos.codehot.tech/misc/ios-webapp-example2.html
私は自分の考えにコメントしたり、部分的に答えたり、共有したりしたいです。私は、今後予定されている私のプロジェクトでは、overflow-y:scroll技法を使用しています。それを使用すると、2つの大きな利点があります。
a)あなたは、画面の下からアクションボタン付きの引き出しを使うことができます。文書がスクロールして下部のバーが消えた場合は、画面の下部にあるボタンをタップすると最初に下部のバーが表示され、次にクリック可能になります。また、これが機能する方法は、一番下にボタンがあるモーダルで問題を引き起こします。
b)オーバーフローした要素を使用している場合、CSSの大幅な変更があった場合に再描画されるのは、表示可能画面にあるものだけです。 javascriptを使用して複数の要素のCSSをその場で変更すると、これによってパフォーマンスが大幅に向上しました。たとえば、再描画する必要がある20個の要素のリストがあり、そのうち2つのみがオーバーフローした要素に画面上に表示されている場合、スクロール時に残りの部分が再描画されます。それがなければ、20の要素すべてが再描画されます。
もちろん、それはプロジェクトに依存し、あなたが私が言及した機能のうちのどれかを必要とするならば。 Googleは、a)で説明した機能を使用するためにgmailにオーバーフロー要素を使用しています。 Imo、古いiPhoneの高さが小さいことを考慮しても(372px)、その価値はしばらくあります。
IOSとAndroidの両方でWebアプリケーションをフルスクリーンで実行することは可能です。 それはPWA と呼ばれ、大変な作業の後、この問題を回避する唯一の方法でした。
PWAは、見逃してはいけない、開発のための興味深いオプションをいくつか公開しています。私はすでにカップルを作りました、デザイナーのためのこのパブリックとプライベートの入札説明書(スペイン語)をチェックしてください。 そしてこれがCosmicJSサイトからの英語の説明です