ブラウザのビューポートのサイズを取得するにはどうすればよいですか?


789

訪問者に画像を高品質で表示する機能を提供したいのですが、ウィンドウサイズを検出する方法はありますか?

あるいはもっと良いのは、JavaScriptを搭載したブラウザのビューポートサイズですか。ここの緑のエリアを参照してください:


10
私がすることは、要素を通常htmlの高さに100%設定し、その高さを取得することです。シンプルはどこでも動作します。
Muhammad Umer 2014年

1
@MuhammadUmer良いキャッチ!寸法の取得に不満を感じた場合は(jQueryを使用しない携帯電話では)、getComputedStyle拡張htmlタグを使用できます。
Dan

また、ブラウザ間のビューポート検出を処理するWライブラリを使用することもできます;)
pyrsmk

回答:


1328

クロスブラウザ @media (width)@media (height)値 

const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);

window.innerWidth そして .innerHeight

  • CSSビューポート @media (width)を取得@media (height)し、スクロールバーを含みます
  • initial-scaleズームの変動により、モバイルの値がPPKがビジュアルビューポートと呼ぶ値に誤って縮小され、値よりも小さくなる場合があります。@media
  • ズームにより、ネイティブの丸めが原因で値が1pxずれることがあります
  • undefined IE8の

document.documentElement.clientWidth そして .clientHeight

資源


4
01100001 @に置き換え$verge。jQueryに統合する場合は、を実行してくださいjQuery.extend(verge)。参照:verge.airve.com/#static
ライアンブ

4
IE8(およびおそらく他のバージョン)<!DOCTYPE html>では、コードを機能させるために、ページの上部にを配置する必要があることを述べたかっただけです。
Tzury Bar Yochay 2013年

6
モバイルデバイスのclientWidth / Heightには満足していません。tripleodeon.com/ wp
Dan

24
私が何かを逃していない限り、この答えは間違っています。Chromeで、少なくとも、document.documentElement.clientHeight戻りページの高さにしながら、window.innerHeightリターンビューポートの高さ。大きな違い。
2015

2
さまざまな画面サイズの変数/ソリューションのライブテスト:ryanve.com/lab/dimensions
Alex Pandrea

106

jQueryディメンション関数

$(window).width() そして $(window).height()


60
@allyourcode、不可能、jQueryはすべての答えです。
Xeoncross 2011年

21
これはビューポートサイズを取得しませんが、ドキュメント全体のサイズを取得します。それを試してみてください。
アレハンドロガルシアイグレシアス

2
アドオンツールバーを固定位置付けのHTMLとして表示するブラウザーでは、この解決策は機能しません。特に、コードの上位の配置とパーセンテージで使用する場合はそうです。
Adib Aroui 2014年

7
@AlejandroIglesias:いいえ、このSOページでテストしました。$(window).height();は536を$("html").height();返しますが、10599を返します
Flimm

2
警告これらの寸法にはスクロールバー(ブラウザーやプラットフォームによってサイズが異なる)が含まれていないため、CSSメディアクエリと一致しませんが、他の回答はこの問題を解決します。
スペンサーオライリー2017年

75

window.innerWidthおよびwindow.innerHeightプロパティを使用できます。

innerHeightとouterHeight


29
これはIE +1では図表:Dに対して機能しません。このような質問については、これらの多くを持たないことは犯罪であるべきです。
allyourcode 2009

8
@CMS document.documentElement.clientWidthはより正確で広くサポートされていますwindow.innerWidth
ライアンブ2012年

6
@ryanve「より正確に」とは、「リモートで同じことをすることすらしない」ことを意味する場合、はい:P
ボックス化された

Firefox Beta?それは博物館に属していたものです。
Derek款會功夫2014年

@boxedモバイルSafariではdocument.documentElement.clientWidth、ビューポートの幅が表示され、window.innerWidthでドキュメントの幅が表示されます。はい、その通りです。
ジョン

33

jQueryを使用していない場合、醜くなります。以下は、すべての新しいブラウザで動作するはずのスニペットです。動作は、IEのQuirksモードと標準モードで異なります。これで大丈夫です。

var elem = (document.compatMode === "CSS1Compat") ? 
    document.documentElement :
    document.body;

var height = elem.clientHeight;
var width = elem.clientWidth;

8
これはビューポートではなくページの高さを与えませんか?それがこのページが示しているようです:developer.mozilla.org/en/DOM/element.clientHeight
allyourcode

4
要素で使用clientHeightしているdocument.documentElementため、ビューポートのサイズがわかります。ドキュメントサイズを取得するには、を実行する必要がありますdocument.body.clientHeight。Chetanが説明するように、この動作は最新のブラウザに適用されます。テストは簡単です。コンソールを開いて、開いているdocument.documentElement.clientHeightいくつかのタブに入力するだけです。
Gajus 2014年

13

私はこれが許容できる答えであることを知っていますが、clientWidthiPhone(少なくとも私のもの)が320ではなく980を返したので、私は機能しなかった状況に遭遇しましたwindow.screen.width。私は既存のサイトで作業していて、「レスポンシブ」になり、より大きなブラウザに異なるメタビューポートを使用するように強制する必要がありました。

これが誰かを助けてくれることを願っていますが、完璧ではないかもしれませんが、iOとAndroidでの私のテストでは機能します。

//sweet hack to set meta viewport for desktop sites squeezing down to mobile that are big and have a fixed width 
  //first see if they have window.screen.width avail
  (function() {
    if (window.screen.width)
    {
      var setViewport = {
        //smaller devices
        phone: 'width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no',
        //bigger ones, be sure to set width to the needed and likely hardcoded width of your site at large breakpoints  
        other: 'width=1045,user-scalable=yes',
        //current browser width
        widthDevice: window.screen.width,
        //your css breakpoint for mobile, etc. non-mobile first
        widthMin: 560,
        //add the tag based on above vars and environment 
        setMeta: function () {
          var params = (this.widthDevice <= this.widthMin) ? this.phone : this.other; 
          var head = document.getElementsByTagName("head")[0];
          var viewport = document.createElement('meta');
          viewport.setAttribute('name','viewport');
          viewport.setAttribute('content',params);
          head.appendChild(viewport);
        }
      }
      //call it 
      setViewport.setMeta();
    }
  }).call(this);

13

私はクロスブラウザの方法を探して見つけました:

function myFunction(){
  if(window.innerWidth !== undefined && window.innerHeight !== undefined) { 
    var w = window.innerWidth;
    var h = window.innerHeight;
  } else {  
    var w = document.documentElement.clientWidth;
    var h = document.documentElement.clientHeight;
  }
  var txt = "Page size: width=" + w + ", height=" + h;
  document.getElementById("demo").innerHTML = txt;
}
<!DOCTYPE html>
<html>
  <body onresize="myFunction()" onload="myFunction()">
   <p>
    Try to resize the page.
   </p>
   <p id="demo">
    &nbsp;
   </p>
  </body>
</html>


stackoverflowがコードスニペットを囲むiframeを使用すると結果が台無しになることに注意してください
Miller

11

私はJavaScriptで決定的な答えを見つけることができました:O'Reillyによる第6版、最終版、p。391:

このソリューションはQuirksモードでも機能しますが、ryanveとScottEverndenの現在のソリューションは機能しません。

function getViewportSize(w) {

    // Use the specified window or the current window if no argument
    w = w || window;

    // This works for all browsers except IE8 and before
    if (w.innerWidth != null) return { w: w.innerWidth, h: w.innerHeight };

    // For IE (or any browser) in Standards mode
    var d = w.document;
    if (document.compatMode == "CSS1Compat")
        return { w: d.documentElement.clientWidth,
           h: d.documentElement.clientHeight };

    // For browsers in Quirks mode
    return { w: d.body.clientWidth, h: d.body.clientHeight };

}

なぜ線if (document.compatMode == "CSS1Compat")がそうでないのか不思議に思うことを除いてif (d.compatMode == "CSS1Compat")、すべてがよく見えます。


Retinaディスプレイ、Landscape vs Portrait、またはメタビューポートタグのことですか?snowdragonledhk.com/…のように仮想ピクセルを意味するのではありませんか?
非極性

1)高DPIディスプレイについて話すとき、私はここで説明されている仮想ピクセルを意味します:stackoverflow.com/a/14325619/139361。すべてのiPhone画面の幅はちょうど320仮想ピクセルです。2)私は次のように言います:a)documentElement.clientWidthiOSでのデバイスの向きの変更に応答しません。b)仮想ピクセルの代わりに物理ピクセル数(実際には役に立たない)を表示
Dan

11

モバイルの仮想ピクセルに正しい値を与える非jQueryソリューション探していて、問題が明白であるwindow.innerHeightdocument.documentElement.clientHeight解決できると思われる場合は、まずこのリンクを調べてください:https : //tripleodeon.com/assets/2011/12/ table.html

開発者は問題を明らかにする適切なテストを実施しました。Android/ iOS、横向き/縦向き、通常/高密度のディスプレイで予期しない値を取得する可能性があります。

私の現在の答えはまだ特効薬(// todo)ではなく、このスレッドから本番用コードに任意のソリューションをすばやくコピーアンドペーストする人への警告です。

私はモバイルで仮想ピクセルのページ幅を探していましたが、動作するコードは(予期せず)のみであることがわかりましたwindow.outerWidth。時間があるときに、ナビゲーションバーを除いた高さを与える正しい解決策について、この表を後で調べます。



9

とには違いがwindow.innerHeightありdocument.documentElement.clientHeightます。1つ目は、水平スクロールバーの高さを含みます。


1
OS全体、Retinaディスプレイ、横向き/縦向きモードで回答をテストしましたか?このリンクはかなり古いシステムをカバーしていますが、コードが機能しないことを証明しています:tripleodeon.com/wp-content/uploads/2011/12/table.html
Dan

6

W3C標準に準拠するソリューションは、透明なdivを(たとえばJavaScriptで動的に)作成し、その幅と高さを100vw / 100vh(ビューポート単位)に設定してから、そのoffsetWidthおよびoffsetHeightを取得することです。その後、要素は再び削除できます。ビューポートユニットは比較的新しいので、これは古いブラウザーでは機能しませんが、それらを気にせず、代わりに(間もなく)標準について気にする場合は、間違いなくこの方法を使用できます。

var objNode = document.createElement("div");
objNode.style.width  = "100vw";
objNode.style.height = "100vh";
document.body.appendChild(objNode);
var intViewportWidth  = objNode.offsetWidth;
var intViewportHeight = objNode.offsetHeight;
document.body.removeChild(objNode);

もちろん、objNode.style.position = "fixed"を設定して、幅/高さとして100%を使用することもできます。これにより、同じ効果が得られ、互換性がある程度向上します。また、位置を固定に設定することは一般的に良い考えです。そうしないと、divは表示されなくなりますが、スペースを消費し、スクロールバーが表示されるなどになります。


残念ながら、現実は「W3C-標準ソリューション」を完全に破壊します:1)caniuse.com/viewport-units、2caniuse.com/#feat=css-fixed。開発者が必要としているのは、「理論的には機能するはず」ではなく、機能するソリューションです。
Dan

標準に依存できれば、クロスブラウザーソリューションすら必要ありません。仕様に回答するソリューションはソリューションではありません。
デレク━會功夫2014年

3

これが私のやり方です、IE 8-> 10、FF 35、Chrome 40で試しましたが、すべての最新のブラウザー(window.innerWidthが定義されている)とIE 8(ウィンドウなし)で非常にスムーズに動作します。 innerWidth)もスムーズに機能します。問題があれば(オーバーフローによる点滅など: "非表示")、報告してください。一部のレスポンシブツールを回避するためだけにこの関数を作成したので、ビューポートの高さにはあまり興味がありませんが、実装される可能性があります。お役に立てば幸いです。コメントや提案に感謝いたします。

function viewportWidth () {
  if (window.innerWidth) return window.innerWidth;
  var
  doc = document,
  html = doc && doc.documentElement,
  body = doc && (doc.body || doc.getElementsByTagName("body")[0]),
  getWidth = function (elm) {
    if (!elm) return 0;
    var setOverflow = function (style, value) {
      var oldValue = style.overflow;
      style.overflow = value;
      return oldValue || "";
    }, style = elm.style, oldValue = setOverflow(style, "hidden"), width = elm.clientWidth || 0;
    setOverflow(style, oldValue);
    return width;
  };
  return Math.max(
    getWidth(html),
    getWidth(body)
  );
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.