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


186

プロジェクトで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によって計算された幅とCSSによって計算された幅が同じではないように見えることです。とき$(window).width()、751のようにビューポートの幅がそれほどに16pxの異なるがあるように思わ戻っ767 CSSの計算。

これを引き起こしている原因と、私が問題を解決する方法を誰かが知っていますか?人々は、スクロールバーの幅は考慮に入れられておらず、使用$(window).innerWidth() < 751する方法が進むべき道であると示唆しています。ただし、理想的には、スクロールバーの幅を計算し、メディアクエリと一致するソリューション(たとえば、両方の条件が値767をチェックしている場合)を見つけたいと思います。確かに、すべてのブラウザのスクロールバーの幅が16pxになるわけではないのですか?


1
if($( 'html')。width()<= 767){//何かをする}
Vaibs_Cool

@Vaibs_Cool提案に感謝しますが、同じ結果が得られます
Pattle


:ここで私[ここにリンクの説明を入力します] [1] [1]回答stackoverflow.com/questions/11309859/...
Rantiev

(「$(window).width()」の代わりに)「document.documentElement.clientWidth」は、希望どおりに機能しますか?編集:私の間違い、Vaibs_Coolの答えを見たところです。
joshhunt 14年

回答:


292

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

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

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

更新:

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

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

8
Modernizrライブラリを使用する余裕があれば、これが最良の答えです。
richsinn 2014

1
このソリューションの方が優れています:stackoverflow.com/a/19292035/1136132(2番目のコード)。JSのみ。
joseantgv

@joseantgv私のソリューションもjsのみです。リンクしたソリューションが優れている理由を説明できますか?
ausi 2015

2
@edwardm Modernizr.mqはブール値のみを返すため、onresizeイベントハンドラで自分で呼び出す必要があります。
ausi

2
@Bernig window.matchMediaは、リフローをトリガーしないため、推奨される方法です。関数を呼び出す頻度によっては、これがパフォーマンスの問題を引き起こす可能性があります。Modernizrを直接使用したくない場合は、src / mq.jsおよびsrc / injectElementWithStyles.jsからソースコードをコピーできます。
ausi 2016

175

メディアクエリが変更される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;
    }
}

9
これは、他の回答で述べたJSハックよりもエレガントなソリューションです。
ルネ・ロス

3
+1これは賢いだけです。ブレークポイントを変更したい場合は、JavaScriptではなくCSSを変更するだけです。
JoeMoe1984

このソリューションは正常に動作し、最も投票された回答で提案されているjavascriptハックよりもエレガントだと思います。
アンドレス・メザ-Escallón

2
あなたは、ブートストラップを使用する場合は、のようなCSSなしでそれを行うことができます<div id="xs-indicator" class="xs-visible">
CAMO

33

これは、が原因である可能性があり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' ] };
}

上記のコードソース


ありがとう。これは機能しますが、とにかくjqueryを使用してスクロールバーの幅を含めることができます。スクロールバーの幅が異なるブラウザーで変化する可能性があると私は考えていますか?
Pattle

1
はい使うinnerWidth()か、のようにそれを使用することができます$('body').innerWidth();参照してください。このstackoverflow.com/questions/8339377/...
ロハン・クマール

3
jQuery $(window)オブジェクトではなくwindow.innerWidthを意味し、$(window).width()はそれを誤って返します
EJanuszewski

1
window.innerWidthOSXシステム設定でスクロールバーが有効になっている場合、Safari 8のCSSメディアクエリとの一貫性がありません。
ausi


4

ドキュメントの幅をJSスコープにするのではなく、css @mediaクエリによって何らかの変更を行う方がよいかもしれません。このメソッドを使用すると、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");
    ...
});

3

私は最近同じ問題に直面していました-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

これは、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を使用して適切な画面幅を取得するのに煩わされる必要はありません。


querySelector()またはを使用する必要はありませんgetPropertyValue()。正規表現でも単一引用符を検索できます(一貫性がないため)。これ:window.getComputedStyle(document.body, ':after').content.replace(/"|'/g, '')。そして、それを少し安くするには、アンダースコア/ロダッシュに〜100ms ._debounce()待機してラップすることができます。最後に、属性を<html>に追加すると、varの外部にある未加工のフラグ/データを検索するツールチップ無効化句などの他のものが出力を利用できるようになります。例:gist.github.com/dhaupin/f01cd87873092f4fe2fb8d802f9514b1
dhaupin

2

JavaScriptは、ビューポートの幅をチェックするための複数のメソッドを提供します。お気づきのとおり、innerWidthにはツールバーの幅が含まれておらず、ツールバーの幅はシステムによって異なります。また、ツールバーの幅を含むouterWidthオプションもあります。MozillaのJavaScriptのAPIの状態:

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

javascriptの状態では、すべてのプラットフォームのすべてのブラウザーで、outerWidthの特定の意味に依存することはできません。

outerWidth古いモバイルブラウザは十分にサポートされていませんが、主要なデスクトップブラウザと最新のスマートフォンブラウザでサポートされています。

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

要約あなただけのデスクトップブラウザと新しいモバイルブラウザ用アプリケーションを開発する場合、outerWidthのはで、あなたが探しているもの、あなたを与える必要があり、いくつかの注意点


1

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

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

詳細については、Mozillaのドキュメントを参照してください。


1

これを試して

getData(){
    if(window.innerWidth <= 768) {
      alert('mobile view')
      return;
    }

   //else function will work

    let body= {
      "key" : 'keyValue'
    }
    this.dataService.getData(body).subscribe(
      (data: any) => {
        this.myData = data
      }
    )
}

0

常に機能し、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
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

私がやること ;

<body>
<script>
function getWidth(){
return Math.max(document.body.scrollWidth,
document.documentElement.scrollWidth,
document.body.offsetWidth,
document.documentElement.offsetWidth,
document.documentElement.clientWidth);
}
var aWidth=getWidth();
</script>
...

その後、任意の場所でaWidth変数を呼び出します。

スクロールバーの幅がカウントされることを確認するには、ドキュメントの本文にgetWidth()を配置する必要があります。そうでない場合は、ブラウザのスクロールバーの幅がgetWidth()から差し引かれます。


-1

滑らかなスライダーを実装し、解像度に応じてブロック内に異なる数のスライドを表示します(jQuery)

   if(window.matchMedia('(max-width: 768px)').matches) {
      $('.view-id-hot_products .view-content').slick({
        infinite: true,
        slidesToShow: 3,
        slidesToScroll: 3,
        dots: true,
      });
    }

    if(window.matchMedia('(max-width: 1024px)').matches) {
      $('.view-id-hot_products .view-content').slick({
        infinite: true,
        slidesToShow: 4,
        slidesToScroll: 4,
        dots: true,
      });
    }

-2

これを試して

if (document.documentElement.clientWidth < 767) {
   // scripts
}

詳細については、ここをクリックしてください


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