Obtenez la largeur de l'appareil en javascript

129

Existe-t-il un moyen d'obtenir la largeur de l'appareil des utilisateurs, par opposition à la largeur de la fenêtre, en utilisant javascript?

Les requêtes multimédias CSS offrent cela, comme je peux le dire

@media screen and (max-width:640px) {
    /* ... */
}

et

@media screen and (max-device-width:960px) {
    /* ... */
}

Ceci est utile si je cible les smartphones en orientation paysage. Par exemple, sur iOS, une déclaration de max-width:640pxciblera à la fois les modes paysage et portrait, même sur un iPhone 4. Ce n'est pas le cas pour Android, pour autant que je sache, donc utiliser la largeur de l'appareil dans ce cas cible avec succès les deux orientations, sans cibler les appareils de bureau.

Cependant , si j'invoque une liaison javascript basée sur la largeur de l'appareil, je semble être limité à tester la largeur de la fenêtre, ce qui signifie un test supplémentaire comme ci-dessous,

if ($(window).width() <= 960 && $(window).height <= 640) { /* ... */ }

Cela ne me semble pas élégant, étant donné l'indication que la largeur de l'appareil est disponible en css.

Nicholas Evans
la source
4
Essayez ce site Web pour connaître les dimensions correctes de votre appareil. responsejs.com/labs/dimensions
Alpesh Darji
Modernizrpeut vous aider à le faire «de manière propre et générique»: stackoverflow.com/questions/25935686/… . En ce qui concerne le 1er commentaire: vous pouvez consulter Google "Modernizr vs <otherLib> media query" pour découvrir ce qui fonctionne le mieux pour votre cas d'utilisation
Adrien Be

Réponses:

214

Vous pouvez obtenir la largeur de l'écran de l'appareil via la propriété screen.width.
Parfois, il est également utile d'utiliser window.innerWidth (qui ne se trouve généralement pas sur les appareils mobiles) au lieu de la largeur de l'écran lorsque vous utilisez des navigateurs de bureau où la taille de la fenêtre est souvent inférieure à la taille de l'écran de l'appareil.

En règle générale, lorsque j'utilise des appareils mobiles ET des navigateurs de bureau, j'utilise les éléments suivants:

 var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
Bryan Rieger
la source
5
J'ai remarqué que cela ne fonctionne pas comme prévu sur le navigateur natif Android 2.2. Si je ne suis pas à une échelle de 1: 1, cela peut rapporter des largeurs beaucoup plus larges (aussi larges que la page peut être), ce qui est un peu frustrant.
Chris Bosco
4
Cela renvoie 980 sur Chrome Beta sur Android et 1024 sur le navigateur Android sur un HTC Vivid.
Alex
4
@Alex Ce sont les largeurs de fenêtre par défaut des navigateurs. Si vous utilisez une balise meta viewport avec, width=device-widthvous devriez obtenir la valeur réelle.
Brian Nickel
2
window.innerWidth renvoie 980 sur Iphone (Chrome / Safari). Comment c'est? <meta name = "viewport" content = "width = device-width" /> n'a fait aucune différence.
Joao Leme
13
Comment cela a-t-il autant de votes positifs? var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;renvoie 667 sur iphone 6 ET 6 Plus. Cette solution ne fonctionne pas correctement.
Ian S
60

Un problème avec la réponse utile de Bryan Rieger est que sur les écrans haute densité, les appareils Apple signalent la largeur de l'écran en creux, tandis que les appareils Android la signalent en pixels physiques. (Voir http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html .) Je suggère d'utiliser if (window.matchMedia('(max-device-width: 960px)').matches) {}sur les navigateurs prenant en charge matchMedia.


la source
1
Cela semble être une bien meilleure solution et utilise en fait des requêtes multimédias CSS. Je me demande quelle est la prise en charge du navigateur pour cela sur les plates-formes mobiles?
Carl Zulauf
1
Serait-ce la bonne utilisation? if (window.matchMedia('(max-device-width: 960px)').matches) { var winW = (window.innerWidth > 0) ? window.innerWidth : screen.width; } else { var winW = screen.width; }
norsewulf
3
Je ne sais pas si cela fonctionnera sans la mise à l'échelle définie sur 1: 1 comme base ...var isMobile = window.matchMedia && window.matchMedia('(max-device-width: 960px)').matches || screen.width <= 960;
Tracker1
3
Pour les navigateurs ne prenant pas en charge, matchMedia()il existe un polyfill: github.com/paulirish/matchMedia.js
AvL
4
Selon caniuse.com, pratiquement tous les navigateurs, y compris les mobiles, prennent en charge window.matchMedia ()
Mark Langer
14

Je viens d'avoir cette idée, alors peut-être qu'elle est à courte vue, mais elle semble bien fonctionner et pourrait être la plus cohérente entre votre CSS et JS.

Dans votre CSS, vous définissez la valeur de largeur maximale pour html en fonction de la valeur d'écran @media:

@media screen and (max-width: 480px) and (orientation: portrait){

    html { 
        max-width: 480px;
    }

    ... more styles for max-width 480px screens go here

}

Ensuite, en utilisant JS (probablement via un framework comme JQuery), il vous suffit de vérifier la valeur max-width de la balise html:

maxwidth = $('html').css('max-width');

Vous pouvez maintenant utiliser cette valeur pour apporter des modifications conditionnelles:

If (maxwidth == '480px') { do something }

Si mettre la valeur max-width sur la balise html semble effrayant, alors peut-être que vous pouvez mettre une balise différente, une qui n'est utilisée qu'à cette fin. Pour mon objectif, la balise html fonctionne bien et n'affecte pas mon balisage.


Utile si vous utilisez Sass, etc .: pour renvoyer une valeur plus abstraite, telle que le nom du point d'arrêt, au lieu de la valeur px, vous pouvez faire quelque chose comme:

  1. Créez un élément qui stockera le nom du point d'arrêt, par exemple <div id="breakpoint-indicator" />
  2. L'utilisation de requêtes multimédias css modifie la propriété de contenu de cet élément, par exemple «large» ou «mobile», etc. (même approche de requête multimédia de base que ci-dessus, mais définissant la propriété css 'content' au lieu de 'max-width').
  3. Obtenez la valeur de la propriété de contenu css en utilisant js ou jquery (jquery par exemple $('#breakpoint-indicator').css('content');), qui renvoie «large», ou «mobile», etc. en fonction de ce que la propriété de contenu est définie par la requête multimédia.
  4. Agissez sur la valeur actuelle.

Vous pouvez maintenant agir sur les mêmes noms de point d'arrêt que dans sass, par exemple sass: @include respond-to(xs)et js if ($breakpoint = "xs) {}.

Ce que j'aime particulièrement à ce sujet, c'est que je peux définir mes noms de points d'arrêt en css et en un seul endroit (probablement un document scss à variables) et mes js peuvent agir indépendamment.

RogerRoger
la source
8

var width = Math.max(window.screen.width, window.innerWidth);

Cela devrait gérer la plupart des scénarios.

ZNS
la source
Math.max (window.innerWidth); vous donnera la largeur, y compris les barres de défilement dans FireFox, Edge et Chrome. document.documentElement.clientWidth; donnera la largeur à l'intérieur de toutes les barres de défilement de ces navigateurs. Dans IE 11, les deux afficheront la largeur, barres de défilement comprises.
RationalRabbit
7

Tu devrais utiliser

document.documentElement.clientWidth

Il est considéré comme une compatibilité entre navigateurs et est la même méthode que jQuery (window) .width (); les usages.

Pour des informations détaillées, consultez: https://ryanve.com/lab/dimensions/

FooBar
la source
5

Je pense que l'utilisation window.devicePixelRatioest plus élégante que la window.matchMediasolution:

if (window.innerWidth*window.devicePixelRatio <= 960 
    && window.innerHeight*window.devicePixelRatio <= 640) { 
    ... 
}
Maxime Schoeni
la source
5

vous pouvez facilement utiliser

document.documentElement.clientWidth

Reundo
la source
3
En général, les réponses sont beaucoup plus utiles si elles incluent une explication de ce que le code est censé faire et pourquoi cela résout le problème sans en présenter d'autres.
Tim Diekmann
3

Les téléphones Lumia donnent une mauvaise largeur d'écran (au moins sur l'émulateur). Alors peut Math.min(window.innerWidth || Infinity, screen.width)- être fonctionnera sur tous les appareils?

Ou quelque chose de plus fou:

for (var i = 100; !window.matchMedia('(max-device-width: ' + i + 'px)').matches; i++) {}
var deviceWidth = i;
Munawwar
la source
2

Ya mybe vous pouvez utiliser document.documentElement.clientWidth pour obtenir la largeur de l'appareil du client et continuer à suivre la largeur de l'appareil en mettant sur setInterval

juste comme

setInterval(function(){
        width = document.documentElement.clientWidth;
        console.log(width);
    }, 1000);
J. Pat
la source
Utilisez simplement onresize. Par exemple document.getElementsByTagName ("BODY") [0] .onresize = function ()
RationalRabbit
0

Tout comme un FYI, il existe une bibliothèque appelée breakpoints qui détecte la largeur maximale définie dans CSS et vous permet de l'utiliser dans des conditions JS if-else en utilisant les signes <=, <,>,> = et ==. Je l'ai trouvé très utile. La taille de la charge utile est inférieure à 3 Ko.

Abhishek Divekar
la source