web-dev-qa-db-fra.com

Obtenir la largeur de l'appareil en javascript

Existe-t-il un moyen d'obtenir la largeur du périphérique de l'utilisateur, par opposition à la largeur de la fenêtre d'affichage, en utilisant javascript?

Les requêtes de médias CSS offrent ceci, 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 des smartphones en orientation paysage. Par exemple, sur iOS, une déclaration de max-width:640px ciblera à la fois les modes paysage et portrait, même sur un iPhone 4. Ce n'est pas le cas pour Android, autant que je sache, donc utiliser device-width dans ce cas cible avec succès les deux orientations, sans cibler les appareils de bureau.

Cependant, si j'appelle une liaison javascript basée sur la largeur du périphérique, il semble que je sois limité à tester la largeur de la fenêtre d'affichage, 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é que la largeur de périphérique est disponible en CSS.

111
Nicholas Evans

Vous pouvez obtenir la largeur d'écran du périphérique via la propriété screen.width.
Parfois, il est également utile d’utiliser window.innerWidth (que l’on ne trouve généralement pas sur les appareils mobiles) au lieu de la largeur d’écran lorsqu’il s’agit de 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 périphériques mobiles ET des navigateurs de bureau, j'utilise les éléments suivants:

 var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
189
Bryan Rieger

La réponse utile de Bryan Rieger pose un problème: sur les écrans haute densité, Apple appareils signalent screen.width en creux, alors que Android appareils le 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.

52
user69173

J'ai juste eu cette idée, alors peut-être que c'est une vision à court terme, 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 max-width du code HTML en fonction de la valeur de l'é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 tel que JQuery), il vous suffira 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 placer la valeur max-width sur la balise html vous semble effrayant, vous pouvez peut-être utiliser une autre balise, utilisée uniquement à cette fin. Pour ce faire, le tag html fonctionne bien et n’affecte pas mon balisage.


tile 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 effectuer les opérations suivantes:

  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édia css modifie la propriété content de cet élément, e. g. "large" ou "mobile", etc. (même approche de requête multimédia de base que ci-dessus, mais en 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 "grand" ou "mobile", etc. en fonction de la propriété définie par la requête multimédia.
  4. Agir sur la valeur actuelle.

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

Ce que j’aime particulièrement à propos de cela, c’est que je peux définir tous mes noms de points de rupture en css et à un endroit (probablement un document scss de variables) et que js peut agir sur eux indépendamment.

12
RogerRoger

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

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

6
ZNS

Je pense que l'utilisation de window.devicePixelRatio est plus élégante que la solution window.matchMedia:

if (window.innerWidth*window.devicePixelRatio <= 960 
    && window.innerHeight*window.devicePixelRatio <= 640) { 
    ... 
}
4
maxime schoeni

vérifie ça

const mq = window.matchMedia( "(min-width: 500px)" );

if (mq.matches) {
  // window width is at least 500px
} else {
  // window width is less than 500px
}

https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia

3
MEAbid

Les téléphones Lumia donnent une erreur screen.width (au moins sur l’émulateur). Alors peut-être que Math.min(window.innerWidth || Infinity, screen.width) 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;
2
Munawwar

vous pouvez facilement utiliser

document.documentElement.clientWidth

2
Re Undo