2019年の時点で、Mobile Safariを含む<div>をブラウザウィンドウに正確に合わせる方法


10

私は1ページのWebアプリに取り組んでいます。これは、モバイルデバイスで最も一般的に使用されます。その機能の1つはマップモードで、ブラウザウィンドウ全体を一時的に引き継ぎます。距離スケールといくつかのコントロールは、マップの四隅に接続されています。これが地図の小さなスクリーンショットですので、私が何を話しているのかわかります。

地図オーバーレイのスクリーンショット

マップはAとして実装される<div>position: fixed、すべての4点の座標ゼロ。また、マップが表示され<body>ているoverflow: hidden間に一時的にをに設定して、基になるアプリの表示が原点から離れるようにスクロールされる場合を処理します。これで、マップをデスクトップブラウザで正確に機能させることができます。モバイルブラウザーでも"width=device-width,user-scalable=no"、ウィンドウの表示領域をビューポートに正確に対応させるために、メタビューポートタグにのようなものを指定する必要がありました。

私が最初にこのアプリを書いたとき、これはすべて美しく機能しましたが、iOS Safariは、スケーリングに関連するメタビューポートオプションのいずれかを尊重しなくなりました。まだズームできません。現在、このブラウザーでマップを有効にすると、わずかに拡大されたビューが表示され、右側と下部のボタンが切り取られ、何もできなくなります。、すべてのタッチが、ブラウザのスクロールではなく、マップのズーム/パンジェスチャとして解釈されるためです。これらのボタンからアクセスできる機能がないと、マップはそれほど役に立ちません。右上のボタンがないと、マップを閉じることさえできません。唯一の方法は、ページをリロードすることです。これにより、保存されていないデータが失われる可能性があります。

history.pushState/ の使用を確実に追加しonpopstateて、マップオーバーレイが別のページのように動作するようにします。ブラウザの[戻る]ボタンを使用してマップモードを終了することはできますが、ボタンがないために機能が失われることによる残りの問題には対処できません。

を使用.requestFullscreen()してマップオーバーレイを実装することを検討しましたが、それ以外の場合にアプリが使用できるすべての場所でサポートされるわけではありません。特に、それは明らかにiPhoneでは機能しません。iPadでは、ステータスバーとコンテンツに重なる巨大な「X」ボタンが表示されます。私の距離の目盛りはもう読めないでしょう。とにかく、意味的に私が本当に望んでいるものではありません- 全画面ではなく、全ウィンドウが必要です。

最新のブラウザでフルウィンドウ表示を機能させるにはどうすればよいですか?この件名で見つけることができるすべての情報は、メタビューポートタグの使用について語っていますが、前述のとおり、これは機能しません。


1
@Joehat、アプリの大部分レスポンシブです。それは問題ではありません。問題があるのはこのマップオーバーレイ機能だけです。タッチジェスチャを使用してマップ(d3.jsによって生成されたSVGです)をズーム/パンし、ブラウザのズームとスクロールを調整する方法がありません。ブラウザが私にビューポートを制御することを許可したとき、それはちょうどうまくいきました。
jasonharper

1
基本的な質問:CSSリセットを使用していますか?何か奇妙なマージンやパディングはありますか?本体は100vw x 100vhに設定されていますか?本体は、マップdivが機能するために相対的に配置されていますか?
itsallgoodie

1
このためのサンプルコードを共有していただけませんか。チェックしてお知らせします
Ranjith v

1
コードを表示してください!!
nikhil sugandh

1
このウィンドウに表示されるコンテンツのスクリーンショットまたはいくつかの例は、何が起こっているかを判断するのに役立ちます。
ブライスハウィットソン

回答:



1

bodyとhtmlの両方の高さを100%に設定する必要があります

   html, body {
       width: 100%;
       height: 100%;
       margin: 0;
    }

1

これらを試しましたか?

width: 100vw;
height: 100vh;
margin: 0;
padding: 0;

(私はあなたvwが幅ではなく意図していると思いますvh...)これを追加することを示唆している要素は何ですか?私はいくつかの場所(でそれを試してみました<html><body>、およびマップ<div>)が、何の違いを見ていません。
jasonharper

これはdiv用です。要素に適用されている変換スケールまたはズームプロパティはありますか?
Rajilesh Panoli

HTMLレベルでの変換はありません。マップのズーム/パンは、それを構成するSVG要素に翻訳を適用することによって行われます。
jasonharper

0

これを試して:

<meta name="viewport" content="width=device-width, height=device-height , 
initial-scale=1.0,user-scalable=no, shrink-to-fit=yes" />

これは何も変更せず、期待する理由もありません。これがshrink-to-fit=yesデフォルトであり、Safariはスケーリングオプションに注意を払いません。
jasonharper


0

これは古い解決策であり、密接に関連しているが完全に同じではない問題に対処するため、適用されるかどうかは不明です:https : //github.com/gajus/brim

これは、minimal-uiに似たソリューションになるはずです。

この回答を参照する別の質問を次に示します 。iOS8で「minimal-ui」ビューポートプロパティが削除されました。他に「ソフトフルスクリーン」ソリューションはありますか?

これがまったく役立つかどうか教えてください。



0

position: fixed長年使用されてきた標準のCSSメソッドを使用するだけの場合。

.divFixedClass{
    position: fixed;
    top:0;
    left:0;
    right:0;
    bottom:0;
}

これはdivをビューポートのフルサイズに自動サイズ設定するだけで、固定された位置を使用して、どれだけスクロールしても所定の位置にロックされます。必要に応じて、本体のスクロールを無効にできます。

html.noScroll, html.noScroll > body{
    overflow:none;
}

したがって、htmlタグにnoScrollクラスを追加するだけで、スクロールが無効になります。その後、もう一度スクロールできるようにしたい場合。


0

これは、マップコントロールとマップレイヤーに2つのレイヤー構造を使用して実装できます。あなたが実際にjavascriptあなたが望むものを実装するために何も必要としないことを意味します(質問のコーディング例は与えられませんでしたが)。あなたはでビューポートを操作することができCSS、それが実際の意味でvwありvh、あなたのコメントに答えるために100vw / 100vhはどのように役立つと思われますか?vビューポートを表すので役立ちます。

例としてスニペットをご覧ください。

問題にコーディングが含まれている場合は、より適切な例(見落とされる可能性のある特定のパラメーターをより正確にする)を提供できます。

PS:マップレイヤーは、スクロール時にズームされる画像によってシミュレートされます。

function zoom(event) {
  event.preventDefault();

  scale += event.deltaY * -0.01;

  // Restrict scale
  scale = Math.min(Math.max(.125, scale), 4);
  if (scale < 1) {
    scale = 1;
  }
  // Apply scale transform
  el.style.transform = `scale(${scale})`;
}
let scale = 1;
const el = document.getElementById('map');
el.onwheel = zoom;
.container {
  position: absolute;
   display: flex;
  align-items: center;
  justify-content: center;
  top: 0;
  left: 0;
  overflow: hidden;
  width: 100vw;
  height: 100vh;
  background-color: transparent;
}

#map {
  width: 100vw;
  height: 100vh;
    background-repeat: no-repeat;
  background-position: center center;
  background-image: url(https://picsum.photos/800/500.webp);
  z-index: 1;
}


#main {
  display: grid;
  position: absolute;
  background-color: transparent;
  top: 0;
  left: 0;
  grid-template-columns: 6rem auto 6rem;
  grid-template-rows: 3rem auto 3rem;
  width: 0;
  height: 0;
 z-index: 2;
}

.t-l {
background: #fc0;
  position: fixed;
  z-index: 2;
  color: #000;
  top; 0;
  left: 0;
  width: 6rem;
  height: 3rem;
  display: block;
  grid-column-start: 1;
  grid-column-end: column1-end;
  grid-row-start: 1;
  grid-row-end: row1-end;
}
.t-r {
background: #0cf;
  position: fixed;
  z-index: 2;
  color: #000;
  top; 0;
  left: calc(100vw-6rem);
  right: 0;
  width: 6rem;
  height: 3rem;
  display: block;
  grid-column-start: 3;
  grid-column-end: column3-end;
  grid-row-start: 1;
  grid-row-end: row1-end;
}
.b-l {
background: #c0f;
  position: fixed;
  z-index: 2;
  color: #000;
  bottom: 0;
  top: calc(100vh-3rem);
  left: 0;
  width: 6rem;
  height: 3rem;
  display: block;
  grid-column-start: 1;
  grid-column-end: column1-end;
  grid-row-start: 3;
  grid-row-end: row3-end;
}
.b-r {
background: #cf0;
  position: fixed;
  z-index: 2;
  color: #000;
  top: calc(100vh-3rem);
  left: 100vw;
  margin-left: -6rem;
  bottom: 0;
  width: 6rem;
  height: 3rem;
  display: block;
  grid-column-start: 3;
  grid-column-end: column3-end;
  grid-row-start: 3;
  grid-row-end: row3-end;
}
<div class="container">

  <div id="main">
    <button class="t-l">top left control</button>
    <button class="t-r">top right control</button>
    <button class="b-l">bottom left control</button>
    <button class="b-r">bottom right control</button>
  </div>
<div id="map"></div>
</div>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.