webentwicklung-frage-antwort-db.com.de

CSS-Medienabfragen und JavaScript-Fensterbreite stimmen nicht überein

Für eine responsive Vorlage habe ich eine Medienabfrage in meinem CSS:

@media screen and (max-width: 960px) {
 body{
 /*  something */
 background:red;
 }
}

Und ich habe eine jQuery-Funktion zum Ändern der Größe auf die Protokollbreite erstellt:

$(window).resize(function() {
 console.log($(window).width());
 console.log($(document).width()); /* same result */
 /* something for my js navigation */
}

Und es gibt einen Unterschied zur CSS-Erkennung und zum JS-Ergebnis, ich habe dieses Meta:

<meta content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width" name="viewport"/> 

Ich nehme an, es liegt an der Bildlaufleiste (15 px). Wie kann ich das besser machen?

50
benoît

Sie haben Recht mit der Bildlaufleiste, weil das CSS die Gerätebreite verwendet, das JS jedoch die Dokumentbreite.

Sie müssen lediglich die Breite des Ansichtsfensters in Ihrem JS-Code messen, anstatt die Funktion jQuery width zu verwenden.

Dieser Code stammt von http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/

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

Ich fand folgenden Code auf http://www.w3schools.com/js/js_window.asp :

var w=window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;

Praktisch funktioniert es genauso wie die Antwort in @Michael Birds Antwort, aber es ist einfacher zu lesen.

Edit: Ich suchte nach einer Methode, um genau die Breite anzugeben, die für CSS-Medienabfragen verwendet wird. Aber der vorgeschlagene funktioniert nicht perfekt auf Safari mit Bildlaufleisten, sorry. Am Ende habe ich modernizr.js in einer zentralen Funktion verwendet und im Rest des Codes habe ich nur überprüft, ob der Anzeigetyp mobil, tablet oder desktop ist. Da ich mich nicht für die Weite interessiere, funktioniert das gut für mich:

getDisplayType = function () {
  if (Modernizr.mq('(min-width: 768px)')){
    return 'desktop';
  }
  else if (Modernizr.mq('(min-width: 480px)')){
    return 'tablet'
  }
  return 'mobile';
};
7
LarS

window.innerWidth ist was Sie brauchen.

if (window.innerWidth <768) funktioniert für 768-Haltepunkte in CSS

4
Ross

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

Füge 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.

1

Hallo, ich benutze diesen kleinen Trick, um JS und CSS auf reaktionsschnellen Seiten problemlos zusammenzubringen:

Testen Sie die Sichtbarkeit eines Elements, das angezeigt wird oder nicht, unter der Bedingung CSS @media size. Mit bootstrap CSS teste ich die Sichtbarkeit eines hidden-xs-Klassenelements

var msg = "a message for U";

/* At window load check initial size  */
if ( $('#test-xsmall').is(':hidden')  ) {
  /* This is a CSS Xsmall situation ! */
  msg = "@media CSS < 768px. JS width = " + $(window).width() + " red ! ";
  $('.redthing-on-xsmall').addClass('redthing').html(msg);

} else {
  /* > 768px according to CSS  */
  msg = "@media CSS > 767px. JS width = " + $(window).width() + " not red ! ";
  $('.redthing-on-xsmall').removeClass('redthing').html(msg);
}


/* And again when window resize  */

$(window).on('resize', function() {
  if ($('#test-xsmall').is(':hidden')) {
    msg = "@media CSS < 768px. JS width = " + $(window).width() + " red ! ";
    $('.redthing-on-xsmall').addClass('redthing').html(msg);
  } else {
    msg = "@media CSS > 767px. JS width = " + $(window).width() + " not red ! ";
    $('.redthing-on-xsmall').removeClass('redthing').html(msg);
  }
});
@media (min-width: 768px) {
  .hidden-xs {
    display: block !important;
  }
}
@media (max-width: 767px) {
  .hidden-xs {
    display: none !important;
  }
}
.redthing-on-xsmall {
  /* need a scrollbar to show window width diff between JS and css */
  min-height: 1500px;
}
.redthing {
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- the CSS managed Element that is tested by JS --> 
<!-- class hidden-xs hides on xsmall screens (bootstrap) -->

<span id="test-xsmall" class="hidden-xs">THIS ELEMENT IS MANAGED BY CSS  HIDDEN on @media lower than 767px</span>


<!-- the responsive element managed by Jquery  -->
<div class="redthing-on-xsmall">THIS ELEMENT IS MANAGED BY JQUERY RED on @media max width 767px </div>
1
fr-info

Meine Erfahrung war, dass die Breite der Medienabfrage document.body.clientWidth verfolgt. Aufgrund einer vertikalen Bildlaufleiste kann das Überprüfen des Dokuments, des Fensters oder des Ansichtsfensters (). Width dazu führen, dass mein JavaScript zu spät ausgeführt wird - nachdem sich die Medienabfrageregel abhängig von der Höhe des Fensters geändert hat.

Durch das Überprüfen von document.body.clientWidth konnte mein Skriptcode konsistent ausgeführt werden, während die Medienabfrageregel in Kraft trat.

@media (min-width: 873px) {
//einige Regeln
}
...

if (document.body.clientWidth> = 873) {
// etwas Code
}

Der Andy Langton Code hat mich dazu gebracht - danke!

1
Jim