$ (Fenster) .width () entspricht nicht der Medienabfrage

186

Ich verwende Twitter Bootstrap für ein Projekt. Neben den Standard-Bootstrap-Stilen habe ich auch einige meiner eigenen hinzugefügt

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

Ich verwende jQuery auch, um die Reihenfolge bestimmter Elemente auf der Seite zu ändern, wenn die Breite des Ansichtsfensters weniger als 767 Pixel beträgt.

$(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"));
    }
}

Das Problem, das ich habe, ist, dass die $(window).width()vom CSS berechnete Breite und die vom CSS berechnete Breite nicht gleich zu sein scheinen. Wenn $(window).width()767 zurückgegeben wird, berechnet das CSS die Breite des Ansichtsfensters als 751, sodass es einen Unterschied von 16 Pixel zu geben scheint.

Weiß jemand, was dies verursacht und wie ich das Problem lösen könnte? Die Leute haben vorgeschlagen, dass die Breite der Bildlaufleiste nicht berücksichtigt wird und die Verwendung der richtige $(window).innerWidth() < 751Weg ist. Im Idealfall möchte ich jedoch eine Lösung finden, die die Breite der Bildlaufleiste berechnet und mit meiner Medienabfrage übereinstimmt (z. B. wenn beide Bedingungen mit dem Wert 767 verglichen werden). Weil sicherlich nicht alle Browser eine Bildlaufleistenbreite von 16px haben werden?

Vieh
quelle
1
Versuchen Sie etwas, wenn ($ ('html').
Width
@ Vaibs_Cool Danke für den Vorschlag, aber ich bekomme immer noch das gleiche Ergebnis
Pattle
Antworte ich hier [ Linkbeschreibung
Rantiev
Funktioniert "document.documentElement.clientWidth" (anstelle von "$ (window) .width ()") so, wie Sie es möchten? Edit: Mein Fehler, habe gerade Vaibs_Cools Antwort gesehen.
Joshhunt

Antworten:

292

Wenn Sie IE9 nicht unterstützen müssen, können Sie einfach window.matchMedia()( MDN-Dokumentation ) verwenden.

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

window.matchMediastimmt voll und ganz mit den CSS-Medienabfragen überein und die Browserunterstützung ist recht gut: http://caniuse.com/#feat=matchmedia

AKTUALISIEREN:

Wenn Sie mehr Browser unterstützen müssen, können Sie die mq-Methode von Modernizr verwenden . Sie unterstützt alle Browser, die Medienabfragen in CSS verstehen.

if (Modernizr.mq('(max-width: 767px)')) {
    //...
} else {
    //...
}
ausi
quelle
8
Wenn Sie es sich leisten können, die Modernizr-Bibliothek zu nutzen, ist dies die beste Antwort.
Richsinn
1
Diese Lösung ist besser: stackoverflow.com/a/19292035/1136132 (2. Code). Nur JS.
Joseantgv
@joseantgv Meine Lösung ist auch nur js. Können Sie erklären, warum die von Ihnen verknüpfte Lösung besser ist?
Ausi
2
@edwardm gibt Modernizr.mqnur einen booleschen Wert zurück, daher müssen Sie ihn selbst in einem onresizeEreignishandler aufrufen .
Ausi
2
@Bernig window.matchMediaist der empfohlene Weg, da er keinen Reflow auslöst , je nachdem, wie oft Sie die Funktion aufrufen, kann dies zu Leistungsproblemen führen. Wenn Sie Modernizr nicht direkt verwenden möchten, können Sie den Quellcode von src / mq.js und src / injizierenElementWithStyles.js kopieren .
Ausi
175

Überprüfen Sie eine CSS-Regel, die die Medienabfrage ändert. Dies funktioniert garantiert immer.

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;
    }
}
NateS
quelle
9
Das ist eine elegantere Lösung als die in den anderen Antworten erwähnten JS-Hacks.
René Roth
3
+1 das ist einfach klug. Mir gefällt, wie Sie, wenn Sie die Haltepunkte ändern möchten, nur das CSS und nicht Javascript ändern müssen.
JoeMoe1984
Diese Lösung funktioniert gut und ich finde sie eleganter als der in der am häufigsten bewerteten Antwort vorgeschlagene Javascript-Hack.
Andrés Meza-Escallón
2
Wenn Sie Bootstrap verwenden, können Sie es ohne CSS wie<div id="xs-indicator" class="xs-visible">
oamo
33

Es kann daran liegen scrollbar, innerWidthanstelle von widthwie zu verwenden

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"));
}

Auch können Sie viewportdergleichen bekommen

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' ] };
}

Über der Codequelle

Rohan Kumar
quelle
Vielen Dank. Dies wird funktionieren, aber gibt es trotzdem? Ich kann jquery verwenden, um die Breite der Bildlaufleiste einzuschließen. Ich denke nur, dass sich die Breite der Bildlaufleiste in verschiedenen Browsern ändern könnte.
Vieh
1
Ja verwenden innerWidth()oder Sie können es wie verwenden $('body').innerWidth();Siehe diese stackoverflow.com/questions/8339377/…
Rohan Kumar
3
Sie meinen window.innerWidth, nicht auf dem jQuery $ (Fenster) -Objekt, $ (Fenster) .width () gibt es falsch zurück
EJanuszewski
1
window.innerWidthstimmt nicht mit CSS-Medienabfragen in Safari 8 überein, wenn Bildlaufleisten in den OSX-Systemeinstellungen aktiviert sind.
Ausi
10

Ja, das liegt an der Bildlaufleiste. Richtige Antwortquelle: Geben Sie hier die Linkbeschreibung ein

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' ] };
}
Rantiev
quelle
4

Es ist vielleicht eine bessere Vorgehensweise, die Breite des Dokuments nicht im JS-Bereich zu erfassen, sondern eine Änderung vorzunehmen, die durch die Abfrage css @media vorgenommen wird. Mit dieser Methode können Sie sicher sein, dass die JQuery-Funktion und die CSS-Änderung gleichzeitig erfolgen.

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");
    ...
});
Grammgramm
quelle
3

Ich hatte kürzlich das gleiche Problem - auch mit Bootstrap 3.

Weder $ .width () noch $ .innerWidth () funktionieren für Sie.

Die beste Lösung, die ich gefunden habe - und die speziell auf BS3 zugeschnitten ist -
ist die Überprüfung der Breite eines .containerElements.

Da Sie wahrscheinlich wissen, wie das .containerElement funktioniert, ist
es das einzige Element, das Ihnen die aktuelle Breite gibt, die durch BS-CSS-Regeln festgelegt wurde.

Also geht es so etwas wie

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");
user3041539
quelle
3

Verwenden

window.innerWidth

Dies löste mein Problem

user4451021
quelle
3

Hier ist eine Alternative zu den zuvor erwähnten Methoden, bei denen etwas über CSS geändert und über Javascript gelesen werden muss. Diese Methode benötigt window.matchMediaoder Modernizr nicht. Es benötigt auch kein zusätzliches HTML-Element. Es funktioniert mithilfe eines HTML-Pseudoelements, um Haltepunktinformationen zu speichern:

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";
  }
}

Ich habe bodyals Beispiel verwendet, Sie können dafür jedes HTML-Element verwenden. Sie können dem Pseudoelement eine beliebige Zeichenfolge oder Zahl hinzufügen content. Muss nicht "mobil" sein und so weiter.

Jetzt können wir diese Informationen aus Javascript folgendermaßen lesen:

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

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

Auf diese Weise sind wir immer sicher, dass die Haltepunktinformationen korrekt sind, da sie direkt aus CSS stammen und wir uns nicht die Mühe machen müssen, die richtige Bildschirmbreite über Javascript zu erhalten.

dschenk
quelle
Sie müssen nicht verwenden querySelector()oder getPropertyValue(). Sie können auch in Regex nach einem einfachen Anführungszeichen suchen (da es nicht konsistent ist). Dies : window.getComputedStyle(document.body, ':after').content.replace(/"|'/g, ''). Und um das etwas billiger zu machen, können Sie es ._debounce()mit ~ 100 ms Wartezeit in Unterstrich / Lodash einwickeln. Durch das Anhängen von Attributen an <html> wird die Ausgabe für andere Dinge verfügbar, z. B. für Tooltip-Deaktivierungsklauseln, die nach Rohflags / Daten außerhalb von vars suchen. Beispiel: gist.github.com/dhaupin/f01cd87873092f4fe2fb8d802f9514b1
Dhaupin
2

Javascript bietet mehr als eine Methode zum Überprüfen der Breite des Ansichtsfensters. Wie Sie bemerkt haben, enthält innerWidth die Symbolleistenbreite nicht, und die Symbolleistenbreiten unterscheiden sich systemübergreifend. Es gibt auch die Option OuterWidth , die die Breite der Symbolleiste enthält. Die Mozilla Javascript API gibt Folgendes an:

Window.outerWidth ruft die Breite der Außenseite des Browserfensters ab. Es stellt die Breite des gesamten Browserfensters dar, einschließlich Seitenleiste (falls erweitert), Fensterchrom und Fenstergröße / -griffe.

Der Status von Javascript ist so, dass man sich nicht in jedem Browser auf jeder Plattform auf eine bestimmte Bedeutung für OuterWidth verlassen kann.

outerWidthwird in älteren mobilen Browsern nicht gut unterstützt , obwohl es in allen wichtigen Desktop-Browsern und den meisten neueren Smartphone-Browsern unterstützt wird.

Wie ausi betonte, matchMediawäre dies eine gute Wahl, da CSS besser standardisiert ist (matchMedia verwendet JS, um die von CSS erkannten Ansichtsfensterwerte zu lesen). Aber selbst bei akzeptierten Standards gibt es immer noch verzögerte Browser, die sie ignorieren (IE <10 in diesem Fall, was matchMedia zumindest bis zum Tod von XP nicht sehr nützlich macht).

In Zusammenfassung , wenn Sie sind für Desktop - Browser und neue mobile Browser entwickeln, sollte outer Sie, was Sie suchen, mit einigen Einschränkungen .

fzzylogic
quelle
1

Hier ist ein weniger komplizierter Trick, um mit Medienanfragen umzugehen. Die browserübergreifende Unterstützung ist etwas einschränkend, da sie den mobilen IE nicht unterstützt.

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

Weitere Informationen finden Sie in der Mozilla-Dokumentation .

user2128205
quelle
1

Versuche dies

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
      }
    )
}
DINESH Adhikari
quelle
0

Problemumgehung, die immer funktioniert und mit CSS-Medienabfragen synchronisiert wird.

Fügen Sie dem Körper ein Div hinzu

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

Fügen Sie einen Stil hinzu und ändern Sie ihn, indem Sie eine bestimmte Medienabfrage eingeben

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

Überprüfen Sie dann in JS den Stil, den Sie ändern, indem Sie eine Medienabfrage eingeben

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

Im Allgemeinen können Sie also jeden Stil überprüfen, der geändert wird, indem Sie eine bestimmte Medienabfrage eingeben.

Arsen Pyuskyulyan
quelle
0

Die beste browserübergreifende Lösung ist die Verwendung von Modernizr.mq

Link: https://modernizr.com/docs/#mq

Mit Modernizr.mq können Sie programmgesteuert prüfen, ob der aktuelle Status des Browserfensters mit einer Medienabfrage übereinstimmt.

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

Hinweis Der Browser unterstützt keine Medienabfragen (z. B. alter IE). Mq gibt immer false zurück.

Sanjib Debnath
quelle
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);

        });

    }
Adam Colton
quelle
0

Was ich mache ;

<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>
...

und rufen Sie danach irgendwo eine aWidth-Variable auf.

Sie müssen getWidth () in Ihren Dokumentkörper einfügen, um sicherzustellen, dass die Breite der Bildlaufleiste gezählt wird. Andernfalls wird die Breite der Bildlaufleiste des Browsers von getWidth () abgezogen.

burkul
quelle
-1

Implementierung Slick Slider und Anzeige unterschiedlicher Anzahl von Folien im Block abhängig von der Auflösung (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,
      });
    }
Vitalii
quelle
-2

Versuche dies

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

Für weitere Informationen klicken Sie hier

Vaibs_Cool
quelle
Danke, das hat immer noch das gleiche Ergebnis
Pattle