web-dev-qa-db-ja.com

$(window).width()はメディアクエリと同じではありません

プロジェクトでTwitter Bootstrapを使用しています。デフォルトのブートストラップスタイルと同様に私も私自身のいくつかを追加しました

//My styles
@media (max-width: 767px)
{
    //CSS here
}

私はまた、ビューポートの幅が767pxより小さいときにページ上の特定の要素の順序を変更するためにjQueryを使用しています。

$(document).load($(window).bind("resize", checkPosition));

function checkPosition()
{
    if($(window).width() < 767)
    {
        $("#body-container .main-content").remove().insertBefore($("#body-container .left-sidebar"));
    } else {
        $("#body-container .main-content").remove().insertAfter($("#body-container .left-sidebar"));
    }
}

私が抱えている問題は、$(window).width()によって計算された幅とCSSによって計算された幅が同じではないということです。 $(window).width()が767を返すと、cssはビューポートの幅を751と計算するので、16ピクセルの違いがあるようです。

誰がこれを引き起こしているのか、そしてどうやって問題を解決できるのか知っていますか?スクロールバーの幅を考慮に入れるのではなく、$(window).innerWidth() < 751を使うのが良い方法だと人々は示唆しています。しかし理想的には、スクロールバーの幅を計算し、それが私のメディアクエリと一致する解決策を見つけたい(例えば、両方の条件が値767に対してチェックしている場合)。確かにすべてのブラウザのスクロールバー幅が16ピクセルになるとは限らないからです。

176
Pattle

IE9をサポートする必要がない場合は、window.matchMedia()MDNドキュメント )を使用することができます。

function checkPosition() {
    if (window.matchMedia('(max-width: 767px)').matches) {
        //...
    } else {
        //...
    }
}

window.matchMediaはCSSメディアクエリと完全に一致しており、ブラウザのサポートは非​​常に優れています。 http://caniuse.com/#feat=matchmedia

更新:

より多くのブラウザをサポートする必要がある場合は、 Modernizrのmqメソッド を使用できます。これは、CSSのメディアクエリを理解するすべてのブラウザをサポートします。

if (Modernizr.mq('(max-width: 767px)')) {
    //...
} else {
    //...
}
276
ausi

メディアクエリーが変更されるCSSルールを確認してください。これは常に機能することが保証されています。

http://www.fourfront.us/blog/jquery-window-width-and-media-queries

HTML:

<body>
    ...
    <div id="mobile-indicator"></div>
</body>

Javascript:

function isMobileWidth() {
    return $('#mobile-indicator').is(':visible');
}

CSS:

#mobile-indicator {
    display: none;
}

@media (max-width: 767px) {
    #mobile-indicator {
        display: block;
    }
}
166
NateS

scrollbarが原因である可能性があります。innerWidthではなくwidthを使用してください。

if($(window).innerWidth() <= 751) {
   $("#body-container .main-content").remove()
                                .insertBefore($("#body-container .left-sidebar"));
} else {
   $("#body-container .main-content").remove()
                                .insertAfter($("#body-container .left-sidebar"));
}

また、viewportは以下のようになります。

function viewport() {
    var e = window, a = 'inner';
    if (!('innerWidth' in window )) {
        a = 'client';
        e = document.documentElement || document.body;
    }
    return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}

上記のコードソース

32
Rohan Kumar

はい、それはスクロールバーが原因です。正しい答えのソース: ここにリンクの説明を入力してください

function viewport() {
    var e = window, a = 'inner';
    if (!('innerWidth' in window )) {
        a = 'client';
        e = document.documentElement || document.body;
    }
    return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}
9
Rantiev

文書の幅をJSスコープではなく、css @media queryによって行われる何らかの変更を適用することをお勧めします。この方法では、JQuery関数とCSSの変更が同時に発生することを確認できます。

css:

#isthin {
    display: inline-block;
    content: '';
    width: 1px;
    height: 1px;
    overflow: hidden;
}

@media only screen and (max-width: 990px) {
    #isthin {
        display: none;
    }
}

jquery:

$(window).ready(function(){
    isntMobile = $('#isthin').is(":visible");
    ...
});

$(window).resize(function(){
    isntMobile = $('#isthin').is(":visible");
    ...
});
5
gramgram

つかいます

window.innerWidth

これで私の問題は解決しました

4
user4451021

私は最近同じ問題に直面していました - Bootstrap 3でも同様です。

$ .width()も$ .innerWidth()もあなたのために働きません。

私が思いついた最高の解決策 - そして特にBS3に合わせて -
.container要素の幅をチェックすることです

おそらく.container要素がどのように機能するのかご存知のとおり、
これはBSのCSSルールで設定されている現在の幅を与える唯一の要素です。

だからそれは何かのようになります

bsContainerWidth = $("body").find('.container').width()
if (bsContainerWidth <= 768)
    console.log("mobile");
else if (bsContainerWidth <= 950)
    console.log("small");
else if (bsContainerWidth <= 1170)
    console.log("medium");
else
    console.log("large");
3
user3041539

これは、CSSを介して何かを変更し、それをJavascriptを介して読み取ることに依存する、前述の方法の代替手段です。このメソッドはwindow.matchMediaやModernizrを必要としません。追加のHTML要素も必要ありません。 HTMLの擬似要素を使用してブレークポイント情報を「保存」することで機能します。

body:after {
  visibility: hidden;
  height: 0;
  font-size: 0;
}

@media (min-width: 20em) {
  body:after {
    content: "mobile";
  }
}

@media (min-width: 48em) {
  body:after {
    content: "tablet";
  }
}

@media (min-width: 64em) {
  body:after {
    content: "desktop";
  }
}

例としてbodyを使用しましたが、これには任意のHTML要素を使用できます。擬似要素のcontentには、任意の文字列または数字を追加できます。 「モバイル」などである必要はありません。

これで、次のようにしてJavascriptからこの情報を読み取ることができます。

var breakpoint = window.getComputedStyle(document.querySelector('body'), ':after').getPropertyValue('content').replace(/"/g,'');

if (breakpoint === 'mobile') {
    doSomething();
}

このようにしてブレークポイント情報が正しいことを常に確信しています、なぜならそれはCSSから直接来ていて、Javascriptを通して正しいスクリーン幅を得ることに面倒な必要がないからです。

3
dschenk

Javascriptはビューポートの幅をチェックするための複数の方法を提供します。お気づきのとおり、innerWidthにはツールバーの幅は含まれず、ツールバーの幅はシステムによって異なります。ツールバーの幅を含む outerWidth オプションもあります。 Mozilla Javascript API は次のように述べています。

Window.outerWidthは、ブラウザウィンドウの外側の幅を取得します。サイドバー(拡大されている場合)、ウィンドウクローム、ウィンドウサイズ変更の境界線/ハンドルを含むブラウザウィンドウ全体の幅を表します。

JavaScriptの状態は、すべてのプラットフォーム上のすべてのブラウザでouterWidthの特定の意味に頼ることができないようなものです。

outerWidthでサポートされていません より古い モバイルブラウザ 、それは主要なデスクトップブラウザと最も新しいスマートフォンブラウザの間でサポートを楽しんでいます。

Ausiが指摘したように、CSSはより標準化されているのでmatchMediaは素晴らしい選択です(matchMediaはCSSによって検出されたビューポート値を読むためにJSを使います)。しかし、受け入れられている標準でさえ、それらを無視する遅延ブラウザがまだ存在します(この場合IE <10、少なくともXPが終了するまではmatchMediaはあまり役に立ちません)。

summary で、デスクトップブラウザとより新しいモバイルブラウザのためだけに開発しているなら、outerWidthはあなたが探しているものを与えるべきです、 いくつかの警告

2
fzzylogic

これは、メディアクエリを扱うためのそれほど複雑ではないトリックです。クロスブラウザのサポートはモバイルIEをサポートしていないため、少し制限があります。

     if (window.matchMedia('(max-width: 694px)').matches)
    {
        //do desired changes
    }

詳しくは、 Mozillaのドキュメント をご覧ください。

1
user2128205

回避策は常に機能し、CSSメディアクエリーと同期します。

ボディにdivを追加

<body>
    ...
    <div class='check-media'></div>
    ...
</body>

スタイルを追加し、特定のメディアクエリを入力してスタイルを変更する

.check-media{
    display:none;
    width:0;
}
@media screen and (max-width: 768px) {
    .check-media{
         width:768px;
    }
    ...
}

それからあなたがメディアクエリーに入ることによってあなたが変えているJSチェックスタイルで

if($('.check-media').width() == 768){
    console.log('You are in (max-width: 768px)');
}else{
    console.log('You are out of (max-width: 768px)');
}

そのため、一般的には、特定のメディアクエリを入力することによって変更されているスタイルを確認できます。

0

最良のクロスブラウザソリューションはModernizr.mqを使うことです。

リンク:https://modernizr.com/docs/#mq

Modernizr.mqを使用すると、現在のブラウザウィンドウの状態がメディアクエリと一致するかどうかをプログラムで確認できます。

var query = Modernizr.mq('(min-width: 900px)');
if (query) {
   // the browser window is larger than 900px
}

ブラウザはメディアクエリをサポートしていません(例:古いIE)mqは常にfalseを返します。

0
Sanjib Debnath
if(window.matchMedia('(max-width: 768px)').matches)
    {
        $(".article-item").text(function(i, text) {

            if (text.length >= 150) {
                text = text.substring(0, 250);
                var lastIndex = text.lastIndexOf(" ");     
                text = text.substring(0, lastIndex) + '...'; 
            }

            $(this).text(text);

        });

    }
0
Adam Colton