Comment obtenir les dimensions de la fenêtre d'affichage du navigateur?

789

Je veux donner à mes visiteurs la possibilité de voir des images en haute qualité, existe-t-il un moyen de détecter la taille de la fenêtre?

Ou mieux encore, la taille de la fenêtre d'affichage du navigateur avec JavaScript? Voir l'espace vert ici:

Alix Axel
la source
10
Ce que je fais, c'est définir un élément généralement html à 100% de hauteur et obtenir sa hauteur. Des travaux simples partout.
Muhammad Umer
1
@MuhammadUmer bonne prise! Si vous êtes frustré d'obtenir les dimensions (et vous le ferez, sur les téléphones mobiles sans jQuery), vous pouvez utiliser getComputedStylela htmlbalise étendue .
Dan
En outre, vous pouvez utiliser la bibliothèque W , qui gère la détection des fenêtres multi-navigateurs;)
pyrsmk

Réponses:

1328

Cross-browser @media (width) et @media (height)valeurs 

const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);

window.innerWidth et .innerHeight

  • obtient la fenêtre CSS @media (width) et @media (height)qui inclut des barres de défilement
  • initial-scaleet les variations de zoom peuvent entraîner une réduction incorrecte des valeurs mobiles à ce que PPK appelle la fenêtre d'affichage et être plus petites que les @mediavaleurs
  • le zoom peut entraîner une réduction de 1px des valeurs en raison de l'arrondi natif
  • undefined dans IE8-

document.documentElement.clientWidth et .clientHeight

Ressources

ryanve
la source
4
@ 01100001 Remplacez $par verge. Si vous souhaitez intégrer dans jQuery, faites-le jQuery.extend(verge). Voir: verge.airve.com/#static
ryanve
4
Je voulais juste mentionner que dans IE8 (et peut-être d'autres), vous devez avoir le <!DOCTYPE html>en haut de la page pour que le code fonctionne.
Tzury Bar Yochay
6
Je ne suis pas satisfait de clientWidth / Height sur les appareils mobiles, vraiment tripleodeon.com/wp-content/uploads/2011/12/table.html
Dan
24
À moins que je manque quelque chose, cette réponse est fausse. Dans Chrome, au moins, document.documentElement.clientHeightrenvoie la hauteur de la page , tandis que window.innerHeightrenvoie la hauteur de la fenêtre . Grande différence.
Nate
2
test en direct de différentes variables de taille d'écran / solutions: ryanve.com/lab/dimensions
Alex Pandrea
106

Fonctions de dimension jQuery

$(window).width() et $(window).height()

Scott Evernden
la source
60
@allyourcode, impossible, jQuery est la réponse à tous .
Xeoncross
21
Cela n'obtient pas la taille de la fenêtre, mais la taille globale du document. Essayez-le.
Alejandro García Iglesias
2
Pour les navigateurs qui affichent leurs barres d'outils de complément en HTML avec postitionning fixe, cette solution ne fonctionne pas, surtout si vous souhaitez utiliser dans votre code un positionnement et des pourcentages supérieurs.
Adib Aroui
7
@AlejandroIglesias: Non, je viens de le tester sur cette page SO. $(window).height();renvoie 536, tandis que $("html").height();renvoie 10599
Flimm
2
Attention, ces dimensions n'incluent pas les barres de défilement (qui ont des tailles différentes dans différents navigateurs et plates-formes) et, par conséquent, elles ne correspondront pas aux requêtes multimédias css. D'autres réponses ici ne résolvent cependant pas ce problème.
Spencer O'Reilly
75

Vous pouvez utiliser les propriétés window.innerWidth et window.innerHeight .

innerHeight vsuterHeight

CMS
la source
29
Même si cela ne fonctionne pas dans IE +1 pour le diagramme: D. Pour une question comme celle-ci, ce devrait être un crime de ne pas en avoir plus.
allyourcode
8
@CMS document.documentElement.clientWidthest plus précis et plus largement pris en charge quewindow.innerWidth
ryanve
6
@ryanve Si par "plus précis" vous voulez dire "ne fait même pas à distance la même chose" alors oui: P
boxed
Firefox Beta? C'est quelque chose qui appartenait au musée.
Derek 朕 會 功夫
@boxed Dans Safari mobile, document.documentElement.clientWidthme donne la largeur de la fenêtre tandis que window.innerWidth me donne la largeur du document. Oui, de cette façon.
John
33

Si vous n'utilisez pas jQuery, cela devient moche. Voici un extrait qui devrait fonctionner sur tous les nouveaux navigateurs. Le comportement est différent en mode Quirks et en mode standard dans IE. Cela s'en occupe.

var elem = (document.compatMode === "CSS1Compat") ? 
    document.documentElement :
    document.body;

var height = elem.clientHeight;
var width = elem.clientWidth;
Chetan Sastry
la source
8
Cela ne vous donne-t-il pas la hauteur de la page, pas la fenêtre? C'est ce que cette page semble indiquer: developer.mozilla.org/en/DOM/element.clientHeight
allyourcode
4
Vous utilisez clientHeightl' document.documentElementélément, ce qui vous donnera la taille de la fenêtre. Pour obtenir la taille du document, vous devez le faire document.body.clientHeight. Comme l'explique Chetan, ce comportement s'applique aux navigateurs modernes. C'est facile à tester. Ouvrez simplement une console et tapez document.documentElement.clientHeightsur plusieurs onglets ouverts.
Gajus
13

Je sais que cela a une réponse acceptable, mais je me suis retrouvé dans une situation où clientWidthcela ne fonctionnait pas, car l'iPhone (au moins le mien) a retourné 980, pas 320, alors j'ai utilisé window.screen.width. Je travaillais sur un site existant, étant rendu "réactif" et j'avais besoin de forcer des navigateurs plus grands à utiliser une méta-fenêtre différente.

J'espère que cela aide quelqu'un, ce n'est peut-être pas parfait, mais cela fonctionne dans mes tests sur iOs et Android.

//sweet hack to set meta viewport for desktop sites squeezing down to mobile that are big and have a fixed width 
  //first see if they have window.screen.width avail
  (function() {
    if (window.screen.width)
    {
      var setViewport = {
        //smaller devices
        phone: 'width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no',
        //bigger ones, be sure to set width to the needed and likely hardcoded width of your site at large breakpoints  
        other: 'width=1045,user-scalable=yes',
        //current browser width
        widthDevice: window.screen.width,
        //your css breakpoint for mobile, etc. non-mobile first
        widthMin: 560,
        //add the tag based on above vars and environment 
        setMeta: function () {
          var params = (this.widthDevice <= this.widthMin) ? this.phone : this.other; 
          var head = document.getElementsByTagName("head")[0];
          var viewport = document.createElement('meta');
          viewport.setAttribute('name','viewport');
          viewport.setAttribute('content',params);
          head.appendChild(viewport);
        }
      }
      //call it 
      setViewport.setMeta();
    }
  }).call(this);
Jazzy
la source
13

J'ai regardé et trouvé une méthode de navigation croisée:

function myFunction(){
  if(window.innerWidth !== undefined && window.innerHeight !== undefined) { 
    var w = window.innerWidth;
    var h = window.innerHeight;
  } else {  
    var w = document.documentElement.clientWidth;
    var h = document.documentElement.clientHeight;
  }
  var txt = "Page size: width=" + w + ", height=" + h;
  document.getElementById("demo").innerHTML = txt;
}
<!DOCTYPE html>
<html>
  <body onresize="myFunction()" onload="myFunction()">
   <p>
    Try to resize the page.
   </p>
   <p id="demo">
    &nbsp;
   </p>
  </body>
</html>

user2921779
la source
notez que l'utilisation par stackoverflow d'un iframe entourant l'extrait de code perturbe le résultat
Miller
11

J'ai pu trouver une réponse définitive dans JavaScript: The Definitive Guide, 6th Edition by O'Reilly, p. 391:

Cette solution fonctionne même en mode Quirks, contrairement à la solution actuelle de ryanve et ScottEvernden.

function getViewportSize(w) {

    // Use the specified window or the current window if no argument
    w = w || window;

    // This works for all browsers except IE8 and before
    if (w.innerWidth != null) return { w: w.innerWidth, h: w.innerHeight };

    // For IE (or any browser) in Standards mode
    var d = w.document;
    if (document.compatMode == "CSS1Compat")
        return { w: d.documentElement.clientWidth,
           h: d.documentElement.clientHeight };

    // For browsers in Quirks mode
    return { w: d.body.clientWidth, h: d.body.clientHeight };

}

à part le fait que je me demande pourquoi la ligne if (document.compatMode == "CSS1Compat")ne l'est pas if (d.compatMode == "CSS1Compat"), tout a l'air bien.

non-polarité
la source
parlez-vous de l'affichage Retina ou Paysage vs Portrait ou de la balise meta viewport? Vous ne parlez pas de pixels virtuels comme dans snowdragonledhk.com/… ?
non
1) Lorsque je parle d'écrans haute résolution, je veux dire les pixels virtuels expliqués ici: stackoverflow.com/a/14325619/139361 . Chaque écran d'iPhone mesure exactement 320 pixels virtuels. 2) Je dis que: a) documentElement.clientWidthne répond pas au changement d'orientation de l'appareil sur iOS. b) affiche le nombre de pixels physiques (pratiquement inutile) au lieu de pixels virtuels
Dan
11

Si vous recherchez une solution non jQuery qui donne des valeurs correctes en pixels virtuels sur mobile , et que vous pensez que c'est simple window.innerHeightou document.documentElement.clientHeightpeut résoudre votre problème, veuillez d'abord étudier ce lien: https://tripleodeon.com/assets/2011/12/ table.html

Le développeur a fait de bons tests qui révèlent le problème: vous pouvez obtenir des valeurs inattendues pour Android / iOS, paysage / portrait, affichages normal / haute densité.

Ma réponse actuelle n'est pas encore la solution miracle (// todo), mais plutôt un avertissement à ceux qui vont copier-coller rapidement une solution donnée de ce fil dans le code de production.

Je cherchais la largeur de page en pixels virtuels sur mobile, et j'ai trouvé que le seul code fonctionnant est (de manière inattendue!) window.outerWidth. J'examinerai plus tard ce tableau pour une solution correcte donnant la hauteur sans la barre de navigation, quand j'aurai le temps.

Dan
la source
10

Ce code provient de http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/

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

NB: pour lire la largeur, utilisez console.log('viewport width'+viewport().width);

Xavier Blondel
la source
9

Il y a une différence entre window.innerHeightet document.documentElement.clientHeight. Le premier inclut la hauteur de la barre de défilement horizontale.

Szépe Viktor
la source
1
Avez-vous testé votre réponse sur tous les systèmes d'exploitation, sur les écrans Retina et en mode paysage / portrait? Ce lien couvre des systèmes plutôt obsolètes, mais il prouve que votre code ne fonctionne pas: tripleodeon.com/wp-content/uploads/2011/12/table.html
Dan
6

Une solution qui serait conforme aux normes W3C serait de créer une div transparente (par exemple dynamiquement avec JavaScript), de régler sa largeur et sa hauteur sur 100vw / 100vh (unités Viewport), puis d'obtenir ses offsetWidth et offsetHeight. Après cela, l'élément peut être supprimé à nouveau. Cela ne fonctionnera pas dans les navigateurs plus anciens car les unités de la fenêtre sont relativement nouvelles, mais si vous ne vous souciez pas d'elles mais des normes (à venir) à la place, vous pouvez certainement suivre cette voie:

var objNode = document.createElement("div");
objNode.style.width  = "100vw";
objNode.style.height = "100vh";
document.body.appendChild(objNode);
var intViewportWidth  = objNode.offsetWidth;
var intViewportHeight = objNode.offsetHeight;
document.body.removeChild(objNode);

Bien sûr, vous pouvez également définir objNode.style.position = "fixed" puis utiliser 100% comme largeur / hauteur - cela devrait avoir le même effet et améliorer la compatibilité dans une certaine mesure. En outre, définir la position sur fixed peut être une bonne idée en général, car sinon le div sera invisible mais consommera de l'espace, ce qui entraînera l'apparition de barres de défilement, etc.

Firefall
la source
Malheureusement, la réalité détruit complètement votre "solution de normes W3C": 1) caniuse.com/viewport-units , 2) caniuse.com/#feat=css-fixed . Ce dont les développeurs ont besoin, c'est d'une solution qui fonctionne, et non "qui devrait théoriquement fonctionner".
Dan
Si nous pouvons compter sur les normes, nous n'avons même pas besoin de toutes ces solutions multi-navigateurs. Une solution qui répond à la spécification n'est pas une solution.
Derek 朕 會 功夫
3

C'est comme ça que je le fais, je l'ai essayé dans IE 8 -> 10, FF 35, Chrome 40, cela fonctionnera très bien dans tous les navigateurs modernes (comme window.innerWidth est défini) et dans IE 8 (sans fenêtre). innerWidth) cela fonctionne aussi bien, tout problème (comme le clignotement à cause du débordement: "caché"), veuillez le signaler. Je ne suis pas vraiment intéressé par la hauteur de la fenêtre car j'ai créé cette fonction juste pour contourner certains outils réactifs, mais elle pourrait être implémentée. J'espère que cela aide, j'apprécie les commentaires et suggestions.

function viewportWidth () {
  if (window.innerWidth) return window.innerWidth;
  var
  doc = document,
  html = doc && doc.documentElement,
  body = doc && (doc.body || doc.getElementsByTagName("body")[0]),
  getWidth = function (elm) {
    if (!elm) return 0;
    var setOverflow = function (style, value) {
      var oldValue = style.overflow;
      style.overflow = value;
      return oldValue || "";
    }, style = elm.style, oldValue = setOverflow(style, "hidden"), width = elm.clientWidth || 0;
    setOverflow(style, oldValue);
    return width;
  };
  return Math.max(
    getWidth(html),
    getWidth(body)
  );
}
manolinjr81
la source