web-dev-qa-db-fra.com

$ (fenêtre) .width () différent de la requête multimédia

J'utilise Twitter Bootstrap sur un projet. En plus des styles d’amorçage par défaut, j’ai ajouté certains de mes propres

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

J'utilise également jQuery pour modifier l'ordre de certains éléments de la page lorsque la largeur de la fenêtre d'affichage est inférieure à 767 pixels. 

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

Le problème que je rencontre est que la largeur calculée par $(window).width() et la largeur calculée par le CSS ne semblent pas être les mêmes. Lorsque $(window).width() renvoie 767, le css calcule la largeur de la fenêtre comme étant 751, de sorte qu'il semble y avoir une différence de 16 pixels. 

Est-ce que quelqu'un sait ce qui cause ceci et comment je pourrais résoudre le problème? Les gens ont suggéré que la largeur de la barre de défilement ne soit pas prise en compte et que l'utilisation de $(window).innerWidth() < 751 est la voie à suivre. Cependant, idéalement, je souhaite trouver une solution qui calcule la largeur de la barre de défilement et qui soit cohérente avec ma requête multimédia (par exemple, où les deux conditions vérifient la valeur 767). Parce que tous les navigateurs n’auront sûrement pas une largeur de barre de défilement de 16 pixels?

170
Pattle

Si vous n'avez pas besoin de supporter IE9, vous pouvez simplement utiliser window.matchMedia() ( Documentation MDN ).

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

window.matchMedia est tout à fait compatible avec les requêtes de médias CSS et le navigateur est assez bien pris en charge: http://caniuse.com/#feat=matchmedia

METTRE À JOUR:

Si vous devez prendre en charge davantage de navigateurs, vous pouvez utiliser La méthode mq de Modernizr , prend en charge tous les navigateurs qui comprennent les requêtes de supports dans CSS.

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

Vérifiez une règle CSS que la requête multimédia change. Ceci est garanti pour toujours fonctionner.

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;
    }
}
162
NateS

Cela peut être dû à scrollbar, utilisez innerWidth au lieu de width comme

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

Aussi, vous pouvez obtenir le viewport comme 

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

Code ci-dessus Source 

32
Rohan Kumar

oui, c'est à cause de la barre de défilement. Source de réponse correcte: entrez la description du lien ici

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

Il est peut-être préférable de ne pas utiliser JS-scope pour la largeur du document, mais plutôt de modifier la requête css @media. Avec cette méthode, vous pouvez être sûr que la fonction JQuery et le changement CSS se produisent en même temps.

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

Utilisation 

window.innerWidth

Cela a résolu mon problème

4
user4451021

Je faisais face au même problème récemment - également avec Bootstrap 3.

Ni $ .width () ni $ .innerWidth () ne fonctionneront pour vous.

La meilleure solution que j'ai proposée - et est spécialement adaptée à BS3 - 
est à vérifie la largeur d'un élément .container.

Comme vous savez probablement comment fonctionne l'élément .container
c'est le seul élément qui vous donnera la largeur actuelle définie par les règles BS css.

Donc ça va quelque chose comme

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

Voici une alternative aux méthodes mentionnées précédemment qui reposent sur la modification de quelque chose via CSS et sa lecture via Javascript. Cette méthode n'a pas besoin de window.matchMedia ni de Modernizr. Il n'a également besoin d'aucun élément HTML supplémentaire. Cela fonctionne en utilisant un pseudo-élément HTML pour 'stocker' les informations sur les points d'arrêt:

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

J'ai utilisé body comme exemple, vous pouvez utiliser n'importe quel élément HTML pour cela. Vous pouvez ajouter la chaîne ou le nombre de votre choix dans la content du pseudo-élément. Ne doit pas être "mobile" et ainsi de suite.

Maintenant, nous pouvons lire ces informations à partir de Javascript de la manière suivante:

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

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

Ainsi, nous sommes toujours sûrs que les informations sur les points d'arrêt sont correctes, car elles proviennent directement de CSS et nous n'avons pas à nous soucier d'obtenir la bonne largeur d'écran via Javascript.

3
dschenk

Voici un truc moins complexe pour traiter les requêtes des médias. La prise en charge de plusieurs navigateurs est un peu limitée car elle ne prend pas en charge IE mobile.

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

Voir Documentation Mozilla pour plus de détails.

1
user2128205

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

Ajouter une div au corps

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

Ajoutez du style et changez-les en entrant dans une requête multimédia spécifique

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

Puis dans le style de vérification JS que vous modifiez en entrant dans la requête multimédia

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

En règle générale, vous pouvez vérifier tous les styles en cours de modification en entrant dans une requête multimédia spécifique.

0

La meilleure solution multi-navigateurs consiste à utiliser Modernizr.mq

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

Modernizr.mq vous permet de vérifier par programme si l'état actuel de la fenêtre du navigateur correspond à une requête multimédia.

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

Remarque Le navigateur ne prend pas en charge les requêtes de média (par exemple, le vieil IE) mq renverra toujours faux.

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