JavaScriptでデバイスの幅を取得する


128

JavaScriptを使用して、ビューポートの幅ではなく、ユーザーのデバイスの幅を取得する方法はありますか?

CSSメディアクエリはこれを提供します。

@media screen and (max-width:640px) {
    /* ... */
}

そして

@media screen and (max-device-width:960px) {
    /* ... */
}

これは、スマートフォンを横向きでターゲットにしている場合に役立ちます。たとえば、iOSでは、宣言は max-width:640pxiPhone 4でも横向きと縦向きの両方をターゲットにします。Androidの場合、私が知る限り、これは当てはまりません。したがって、このインスタンスでdevice-widthを使用すると、両方の向きを正しくターゲットにできます。デスクトップデバイスを対象としない。

ただし、デバイスの幅に基づいてjavascriptバインディングを呼び出す場合、ビューポートの幅のテストに制限されているようです。これは、次のような追加のテストを意味します。

if ($(window).width() <= 960 && $(window).height <= 640) { /* ... */ }

デバイスの幅がcssで利用可能であるというヒントを考えると、これは私にはエレガントに思えません。


4
このWebサイトを試して、デバイスの正しい寸法を確認してください。responsejs.com/labs/dimensions
Alpesh Darji

Modernizrこれを「クリーンで一般的な方法」で行うのに役立ちます:stackoverflow.com/questions/25935686/…。最初のコメントについて:「Modernizr vs <otherLib>メディアクエリ」をググって、ユースケースに最適なものを見つけることができます
Adrien Be

回答:


215

screen.widthプロパティでデバイスの画面幅を取得できます。
多くの場合、ウィンドウサイズがデバイスの画面サイズよりも小さいデスクトップブラウザを扱う場合は、画面の幅の代わりにwindow.innerWidth(通常はモバイルデバイスにはありません)を使用すると便利です。

通常、モバイルデバイスとデスクトップブラウザーを扱う場合、私は以下を使用します。

 var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;

5
これはAndroid 2.2ネイティブブラウザでは期待どおりに機能しないことに気づきました。1:1のスケールではない場合、幅がはるかに広い(ページが可能な限り広い)ことを報告する可能性があり、これは少しイライラします。
クリス・ボスコ

4
これにより、AndroidのChrome Betaでは980、HTC vividのAndroidブラウザーでは1024が返されます。
アレックス

4
@Alexこれらは、ブラウザのデフォルトのビューポート幅です。ビューポートメタタグを使用する場合はwidth=device-width、実際の値を取得する必要があります。
ブライアンニッケル

2
window.innerWidthはIphone(Chrome / Safari)で980を返します。どう?<meta name = "viewport" content = "width = device-width" />に違いはありませんでした。
Joao Leme

12
これにはどのように多くの賛成票がありますか?var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;iphone 6 AND 6 Plusで667を返します。このソリューションは正しく機能しません。
Ian S

60

Bryan Riegerの有用な回答の1つの問題は、高密度ディスプレイでは、Appleデバイスが画面幅をディップで報告するのに対し、Androidデバイスは物理ピクセルで報告することです。(http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.htmlを参照してください。)if (window.matchMedia('(max-device-width: 960px)').matches) {}matchMediaをサポートするブラウザでの使用をお勧めします。


1
これははるかに優れたソリューションのようで、実際にはCSSメディアクエリを使用しています。これは、モバイルプラットフォーム間でどのようにブラウザでサポートされるのでしょうか。
カールズラウフ2013年

1
これは正しい使い方でしょうか? if (window.matchMedia('(max-device-width: 960px)').matches) { var winW = (window.innerWidth > 0) ? window.innerWidth : screen.width; } else { var winW = screen.width; }
norsewulf 2013

3
スケーリングをベースとして1:1に設定しなくてもこれが機能するかどうかはvar isMobile = window.matchMedia && window.matchMedia('(max-device-width: 960px)').matches || screen.width <= 960;
わかりませ

3
サポートしていないブラウザの場合matchMedia()、ポリフィルがあります:github.com/paulirish/matchMedia.js
AvL '

4
caniuse.comによると、モバイルを含む実質的にすべてのブラウザーがwindow.matchMedia()をサポートしています
Mark Langer

14

私はこのアイデアを持っていたので、多分それは近視眼的ですが、それはうまく機能しているようで、CSSとJSの間で最も一貫しているかもしれません。

CSSで、@ media screen値に基づいてhtmlの最大幅の値を設定します。

@media screen and (max-width: 480px) and (orientation: portrait){

    html { 
        max-width: 480px;
    }

    ... more styles for max-width 480px screens go here

}

次に、JSを使用して(おそらくJQueryのようなフレームワーク経由で)、htmlタグの最大幅の値を確認します。

maxwidth = $('html').css('max-width');

これで、この値を使用して条件付き変更を行うことができます。

If (maxwidth == '480px') { do something }

htmlタグにmax-width値を配置するのが怖いと思われる場合は、この目的でのみ使用される別のタグを配置することができます。私の目的では、htmlタグは正常に機能し、マークアップには影響しません。


Sassなどを使用している場合に便利です。px値の代わりに、ブレークポイント名などのより抽象的な値を返すには、次のようにします。

  1. ブレークポイント名を格納する要素を作成します。例: <div id="breakpoint-indicator" />
  2. cssメディアクエリを使用すると、この要素のコンテンツプロパティが変更されます。たとえば、「ラージ」や「モバイル」などです(上記と同じ基本的なメディアクエリアプローチですが、「max-width」の代わりにcss「content」プロパティを設定します)。
  3. jsまたはjquery(jqueryなど$('#breakpoint-indicator').css('content');)を使用してcssコンテンツプロパティ値を取得します。メディアクエリによってコンテンツプロパティが何に設定されているかに応じて、「大」または「モバイル」などを返します。
  4. 現在の値に基づいて行動します。

これで、sassで行うのと同じブレークポイント名(例:sass:@include respond-to(xs)、js)を操作できif ($breakpoint = "xs) {}ます。

特にこの点で気に入っているのは、ブレークポイント名をすべてcssと1か所(変数のscssドキュメントなど)で定義でき、jsがそれらに独立して動作できることです。


8

var width = Math.max(window.screen.width, window.innerWidth);

これでほとんどのシナリオを処理できます。


Math.max(window.innerWidth); FireFox、Edge、Chromeのスクロールバーを含む幅が表示されます。document.documentElement.clientWidth; これらのブラウザのスクロールバー内の幅を指定します。IE 11では、両方のは、スクロールバーなどの幅が表示されます...
RationalRabbit


5

私は使用するwindow.devicePixelRatio方がwindow.matchMediaソリューションよりエレガントだと思います:

if (window.innerWidth*window.devicePixelRatio <= 960 
    && window.innerHeight*window.devicePixelRatio <= 640) { 
    ... 
}


5

簡単に使える

document.documentElement.clientWidth


3
一般に、コードに意図されていること、および他の人を紹介することなく問題を解決する理由の説明が含まれている場合、回答ははるかに役立ちます。
Tim Diekmann、2018年

3

Lumiaの電話は、間違ったscreen.widthを返します(少なくともエミュレータでは)。それで、おそらくMath.min(window.innerWidth || Infinity, screen.width)すべてのデバイスで動作しますか?

またはもっとクレイジーなもの:

for (var i = 100; !window.matchMedia('(max-device-width: ' + i + 'px)').matches; i++) {}
var deviceWidth = i;

2

ええと、ドキュメントのdocumentElement.clientWidthを使用してクライアントのデバイスの幅を取得し、setIntervalに置くことでデバイスの幅を追跡し続けることができます

と同じように

setInterval(function(){
        width = document.documentElement.clientWidth;
        console.log(width);
    }, 1000);

onresizeを使用してください。たとえば、document.getElementsByTagName( "BODY")[0] .onresize = function()
RationalRabbit

0

参考までに、CSSで設定された最大幅を検出し、<=、<、>、> =、==記号を使用してJS if-else条件で使用できるようにするブレークポイントと呼ばれるライブラリがあります。とても便利だと思いました。ペイロードのサイズは3 KB未満です。

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