web-dev-qa-db-fra.com

Quelles sont les meilleures pratiques pour détecter le rapport / densité de pixels?

J'utilise actuellement JavaScript pour la détection des appareils mobiles sur mon site Web, ce qui me permet ensuite de diffuser différents contenus pour les utilisateurs mobiles ou de bureau.

J'utilise actuellement window.devicePixelRatio et screen.width pour déterminer si l'utilisateur est sur un appareil mobile ou non, comme ceci:

var isMobileScreenWidth = ((screen.width / window.devicePixelRatio) < 768)

768px est le point auquel nous définissons mobile ou ordinateur de bureau, donc 767 et inférieur est mobile et 768 et supérieur est ordinateur de bureau.

Cela fonctionne parfaitement, mais j'ai récemment rencontré un problème avec Firefox, lorsque Firefox est zoomé et dézoomé, il change le window.devicePixelRatio, alors:

zoom = 30%, window.devicePixelRatio = 0.3
zoom = 100%, window.devicePixelRatio = 1.0
zoom = 300%, window.devicePixelRatio = 3.0

Cela me pose maintenant un problème car tous les utilisateurs qui ont leur navigateur zoomé sur Firefox obtiennent la version mobile du site.

Je me demandais si quelqu'un connaissait un moyen différent ou meilleur d'obtenir la densité de pixels qui est distinct des navigateurs de bureau.

J'utilise également une petite quantité de détection d'agent utilisateur, mais comme c'est un travail énorme de suivre la liste en constante évolution des agents utilisateurs mobiles, il ne m'est pas possible de dépendre à la fois de la résolution d'écran et de l'agent utilisateur. temps.

Si quelqu'un a des idées à ce sujet et peut vous aider, ce serait génial.

METTRE À JOUR:

Je viens de tomber sur ceci:

window.screen.availWidth / document.documentElement.clientWidth

Ce petit peu de maths est suggéré dans cet article:

window.devicePixelRatio ne fonctionne pas dans IE 10 Mobile?

Je l'ai testé et cela fonctionne dans Firefox, et résout mon problème, mais, malheureusement, cause maintenant un problème dans Chrome, donc:

Chrome zoom = 100%,
window.devicePixelRatio = 1.0,
window.screen.availWidth / document.documentElement.clientWidth = 3.0

Je n'arrive pas à trouver une solution solide qui fonctionne pour tout.

23
lukehillonline

Vous devez tirer parti de l'indication du fabricant via le <meta name="viewport" content="width=device-width"/> ou @-ms-viewport {width:device-width} fonctionnalité. Il expose essentiellement le zoom par défaut que le fabricant de l'appareil considère optimal compte tenu de la densité de pixels de l'écran. Après cela, lorsque vous appelez window.innerWidth il vous donnera à quoi votre équation d'origine était destinée mais sans compter sur une mesure de la densité de pixels.

Évitez de compter sur window.devicePixelRatio pour rien. Sa signification et la valeur qu'elle retourne sont actuellement dans un état de flux et tout ce que vous faites en ce moment se cassera très probablement très bientôt.

Remarque: la fenêtre Meta ne fonctionne que sur Android, iOS et Windows Phone 8. @-ms-viewport ne fonctionne (correctement) que sur IE10 Metro et peut interférer avec le bon comportement de la fenêtre Meta sur Windows Phone 8.

20
Amann Malik

Il existe une solution générique pour obtenir le ratio de pixels de l'appareil

Le code suivant utilise window.devicePixelRatio Comme point de départ [~ # ~] mais [~ # ~] a également une solution de secours basée sur window.matchMedia() API Web.

Le support du navigateur pour ces deux fonctionnalités est presque parfait, donc cela devrait fonctionner très bien dans la plupart des cas d'utilisation.

Voici une fonction qui récupère ces informations, à l'origine écrite par PatrickJS et publiée sous forme de GitHub Gist :

function getDevicePixelRatio() {
    var mediaQuery;
    var is_firefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
    if (window.devicePixelRatio !== undefined && !is_firefox) {
        return window.devicePixelRatio;
    } else if (window.matchMedia) {
        mediaQuery = "(-webkit-min-device-pixel-ratio: 1.5),\
          (min--moz-device-pixel-ratio: 1.5),\
          (-o-min-device-pixel-ratio: 3/2),\
          (min-resolution: 1.5dppx)";
        if (window.matchMedia(mediaQuery).matches) {
            return 1.5;
        }
        mediaQuery = "(-webkit-min-device-pixel-ratio: 2),\
          (min--moz-device-pixel-ratio: 2),\
          (-o-min-device-pixel-ratio: 2/1),\
          (min-resolution: 2dppx)";
        if (window.matchMedia(mediaQuery).matches) {
            return 2;
        }
        mediaQuery = "(-webkit-min-device-pixel-ratio: 0.75),\
          (min--moz-device-pixel-ratio: 0.75),\
          (-o-min-device-pixel-ratio: 3/4),\
          (min-resolution: 0.75dppx)";
        if (window.matchMedia(mediaQuery).matches) {
            return 0.7;
        }
    } else {
        return 1;
    }
}

Liens utiles : MDN - window.devicePixelRatio , MDN - Window.matchMedia()

CanIUse : window.devicePixelRatio , Window.matchMedia()

4
Andrii Verbytskyi