web-dev-qa-db-fra.com

Les options screen.width, screen.height & window.innerWidth et window.innerHeight du navigateur Android ne sont pas fiables.

Je travaille sur une application Web destinée aux navigateurs des ordinateurs de bureau, des tablettes et des smartphones.

L'application Web comporte une boîte à lumière implémentée à l'aide de Colorbox avec une variable iframe. Lorsque la fenêtre du navigateur est redimensionnée ou que l'orientation de la tablette/du téléphone a été modifiée, le code Javascript interroge les dimensions de la fenêtre afin de pouvoir redimensionner certains éléments de la boîte à lumière.

Le problème que je rencontre est que tout fonctionne correctement sur le bureau (Windows: IE, Firefox, Chrome, Mac: Safari), iPad & iPhone, mais pas sur le smartphone Android (HTC) et l'émulateur Android.

Android renvoie toujours des valeurs différentes pour screen.width, screen.height, window.innerWidth & window.innerHeight quand ils sont interrogés depuis l'événement de redimensionnement de la fenêtre, qui se déclenche plusieurs fois.

Pourquoi le navigateur Android renvoie-t-il une si grande variance de valeurs et comment puis-je détecter de manière fiable la largeur et la hauteur de la fenêtre du navigateur?

29
GiddyUpHorsey

Sur Android, window.outerWidth et window.outerHeight correspondent de manière fiable à la taille de l'écran. En fonction de votre version d'Android, innerWidth/Height est généralement incorrect.

Voici un très bon résumé sur la situation. 

14
six8

J'utilise ceci pour le faire fonctionner entre iOS et Android.

var screenHeight = (ionic.Platform.isIOS()) ? window.screen.height : window.innerHeight * window.devicePixelRatio;
3
Jason Engage

Vous trouverez ci-dessous une différenciation basée sur les lectures effectuées avec Samsung Tab sous Android 4.1.

  • screen.height - donne la hauteur réelle du périphérique, y compris la barre des tâches et la barre de titre

  • window.innerHeight - donne la hauteur excluant la barre des tâches, la barre de titre et la barre d'adresse (si visible)

  • window.outerHeight - donne la hauteur à l'exclusion de la barre des tâches et du titrebar height, (peu importe la barre d'adresse soit visible ou masquée, outerHeight inclut la hauteur de la barre d'adresse.)
3
Ratnakar

J'ai pris des heures pour trouver une solution de contournement.

La seule constante entre window.innerHeight, window.outerheight, etc. était screen.height.

Ce code m'a donné la plus haute:

screen.height / window.devicePixelRatio - window.screenTop

De plus, afin de prendre en charge les anciennes versions d’Android, placez votre code dans une setTimeout

J'espère que c'est utile =)

2
Abdo

Essayez ceci et vérifiez votre lecture mobile

<script>
var total_height=screen.height*window.devicePixelRatio;
alert(total_height);
</script>

Il doit correspondre à la taille de l'écran (hauteur) des spécifications de votre téléphone.

1
Miguel
    var throttle = (function () {
        var timer;

        return function (fn, delay) {
            clearTimeout(timer);
            timer = setTimeout(fn, delay);
      };
    })(),


    var callback = function (w, h) {
        alert(w + ' ' + h);
    }


    window.onresize = throttle(function () {
        width = Math.min(window.innerWidth, window.outerWidth);
        height = Math.min(window.innerHeight, window.outerHeight);

        callback(width, height);
    }, 60);
0
Dan

La réponse de Dan corrige l'incohérence entre le navigateur Android ... donc je poste comment je détecte/modifie la fenêtre d'affichage mobile et l'adapte lors de la rotation (Je ne sais pas s'il est utilisable par quelqu'un ...

var lastorg=0; //set the begining of script
thisorg=parseInt(window.innerWidth)/parseInt(window.innerHeight); //for ratio to detact orietation
if(((lastorg<1 && thisorg>1) ||(lastorg>1 && thisorg<1) ||lastorg==0 )){ //is start or change
$("#viewport").attr('content', 'width=device-width, initial-scale=1,minimum-scale=1, maximum-scale=1'); // reset viewport to device
mywidth = Math.min(window.innerWidth, window.outerWidth); //Dan's way to fix the inconsistancy
myheight = Math.min(window.innerHeight, window.outerHeight);
lastorg=thisorg;    //update the lastorg
wr=parseInt(mywidth)/1280;  // the minimum desire width
hr=parseInt(myheight)/630;  // the minimum desire height
if(hr<wr){
vscale=hr;
if(hr<1){ // if it if small screen, so desktop pc wouldn't change
windowHeight=630;
windowwidth=mywidth/hr;
}
}else{
 vscale=wr;
 if(wr<1){
  windowwidth=1280;
  windowHeight=myheight/wr;
 }
}
$("#viewport").attr('content', 'width=device-width, initial-scale='+vscale+',minimum-scale='+vscale+', maximum-scale='+vscale); //reset viewport toresize window
 if(thisorg>1){
  $("#pro").fadeOut(500);
 }else{
$("body").prepend("<div id=pro style='position:absolute;width:800px;height:30px;padding:30px;left:"+(windowwidth/2)+"px;top:"+(windowHeight/2)+"px;margin-left:-430px;margin-top:-45px;;border:1px solid #555;background:#ddeeff;text-align:center;z-index:99999;color:#334455;font-size:40px;' class=shadowme>Please rotate your phone/tablet</div>");//tell user to rotate
}
}
0
Yuan Shen

Dans mon cas, le hook setTimeout n'était pas utile.

Après quelques recherches, je découvre que différentes versions (et appareils) Android ont des valeurs devicePixelRatio différentes. 

Si devicePixelRatio est égal ou supérieur à 1, le nombre réel de pixels de l'écran (du point de vue de la page html) est donné par window.screen.width (ou ... height). 

Toutefois, si window.screen.width est inférieur à 1 (cela se produit sur certains anciens appareils Android), le nombre réel de pixels devient: window.screen.width/devicePixelRatio.

Donc, vous devez simplement faire face à cela.

w = window.screen.width;
h = window.screen.height;

if(window.devicePixelRatio < 1){
  w = window.screen.width/window.devicePixelRatio;
  h = window.screen.height/window.devicePixelRatio;
}
0
Mauro