53 votes

Les requêtes média CSS et la largeur de la fenêtre JavaScript ne correspondent pas.

Pour un modèle réactif, j'ai une requête média dans mon CSS :

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

Et, j'ai fait une fonction jQuery sur le redimensionnement à la largeur du journal :

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

Et il y a une différence entre la détection CSS et le résultat JS, j'ai cette méta :

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

Je suppose que c'est dû à la barre de défilement (15 px). Comment puis-je faire mieux ?

72voto

Michael Bird Points 516

Vous avez raison au sujet de la barre de défilement, c'est parce que le CSS utilise la largeur du dispositif, mais le JS utilise la largeur du document.

Ce que vous devez faire, c'est mesurer la largeur de la fenêtre d'affichage dans votre code JS au lieu d'utiliser la fonction jQuery width.

Ce code provient de 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' ] };
}

0 votes

Solide. Bien mieux que $(document).width() ; window.matchMedia() est probablement meilleur, mais c'est IE10+.

4 votes

Cela ne semble pas fonctionner si la fenêtre comporte des barres de défilement et si vos requêtes média vérifient la largeur maximale, du moins dans Chrome. En revanche, la vérification de certains éléments css sur un élément dont vous savez qu'il est défini par une requête média particulière semble fonctionner.

0 votes

@mhenry1384 de quoi parlez-vous ?

9voto

LarS Points 86

J'ai trouvé le code suivant sur http://www.w3schools.com/js/js_window.asp :

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

En pratique, cela fonctionne de la même manière que la réponse de @Michael Bird, mais c'est plus facile à lire.

Editar: Je cherchais une méthode pour donner exactement la même largeur que celle utilisée pour les css media queries. Mais la méthode proposée ne fonctionne pas parfaitement sur Safari avec les barres de défilement, désolé. J'ai fini par utiliser modernizr.js dans une fonction centrale et dans le reste du code je vérifie juste si le type d'affichage est mobile, tablette ou desktop. Comme je ne suis pas intéressé par la largeur, cela fonctionne bien pour moi :

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

1 votes

Si document.documentElement n'existe pas, ce script échouera. Ne faites pas confiance à w3schools, voir w3fools.com

3 votes

@ausi : Auriez-vous l'amabilité d'élaborer un peu plus que "ne faites pas confiance à w3schools" ? Je ne vois pas le problème jusqu'à présent. Voir aussi Des problèmes entre navigateurs avec document.documentElement

1 votes

OK, il semble qu'il n'y ait aucun navigateur qui n'ait pas document.documentElement . Je ne le savais pas.

7voto

Ross Points 152

Window.innerWidth est ce dont vous avez besoin.

if (window.innerWidth < 768) fonctionne pour le point d'arrêt 768 en CSS

3voto

Solution de rechange qui fonctionne toujours et qui est synchronisée avec les requêtes média CSS.

Ajouter un div au corps

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

Ajoutez des styles et modifiez-les en entrant dans une requête média spécifique.

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

Ensuite, dans JS, vérifiez le style que vous modifiez en entrant dans media query

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

En général, vous pouvez donc vérifier tout style qui est modifié en entrant dans une requête média spécifique.

1voto

fr-info Points 11

Bonjour, j'utilise cette petite astuce pour que JS et CSS fonctionnent ensemble facilement sur les pages réactives :

Tester la visibilité d'un élément affiché ou non sur la condition CSS @media size. En utilisant le CSS bootstrap, je teste la visibilité d'un élément de classe hidden-xs.

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>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X