¿Cómo obtener las dimensiones de la ventana gráfica del navegador?

789

Quiero proporcionar a mis visitantes la capacidad de ver imágenes en alta calidad, ¿hay alguna forma de detectar el tamaño de la ventana?

O mejor aún, ¿el tamaño de la ventana gráfica del navegador con JavaScript? Ver área verde aquí:

Alix Axel
fuente
10
Lo que hago es establecer un elemento generalmente html al 100% de altura y obtener su altura. Obras simples en todas partes.
Muhammad Umer
1
@MuhammadUmer buena captura! Si se frustra al obtener las dimensiones (y lo hará, en teléfonos móviles sin jQuery), puede getComputedStyleusar la htmletiqueta expandida .
Dan
Además, puede usar la biblioteca W , que maneja la detección de la ventana de visualización del navegador cruzado;)
pyrsmk

Respuestas:

1328

Cross-browser @media (width) y @media (height)valores 

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

window.innerWidth y .innerHeight

  • obtiene la vista CSS @media (width) y @media (height)que incluyen barras de desplazamiento
  • initial-scaley las variaciones de zoom pueden hacer que los valores móviles se escalen incorrectamente a lo que PPK llama la vista visual y sean más pequeños que@media valores
  • el zoom puede hacer que los valores estén 1px desactivados debido al redondeo nativo
  • undefined en IE8-

document.documentElement.clientWidth y .clientHeight

Recursos

ryanve
fuente
44
@ 01100001 Reemplazar $con verge. Si desea integrarse en jQuery, hágalo jQuery.extend(verge). Ver: verge.airve.com/#static
ryanve
44
Solo quería mencionar que en IE8 (y quizás en otros) debe tener el <!DOCTYPE html>en la parte superior de la página para que el código funcione.
Tzury Bar Yochay
66
No estoy satisfecho con clientWidth / Height en dispositivos móviles, realmente tripleodeon.com/wp-content/uploads/2011/12/table.html
Dan
24
A menos que me falte algo, esta respuesta es incorrecta. En Chrome, al menos, document.documentElement.clientHeightdevuelve el alto de la página , mientras que window.innerHeightdevuelve el alto de la ventana gráfica . Gran diferencia.
Nate
2
Prueba en vivo de diferentes tamaños / soluciones de pantalla: ryanve.com/lab/dimensions
Alex Pandrea
106

Funciones de dimensión jQuery

$(window).width() y $(window).height()

Scott Evernden
fuente
6060
@allyourcode, imposible, jQuery es la respuesta para todos .
Xeoncross
21
Esto no obtiene el tamaño de la vista, sino el tamaño general del documento. Intentalo.
Alejandro García Iglesias
2
Para los navegadores que muestran sus barras de herramientas de complementos como HTML con posicionado fijo, esta solución no funciona, especialmente si desea utilizar en el posicionamiento y porcentajes superiores de su código.
Adib Aroui
77
@AlejandroIglesias: No, acabo de probarlo en esta página SO. $(window).height();devuelve 536, mientras que $("html").height();devuelve 10599
Flimm
2
Tenga en cuenta que estas dimensiones no incluyen barras de desplazamiento (que tienen diferentes tamaños en diferentes navegadores y plataformas) y, por lo tanto, no coincidirán con las consultas de medios CSS. Otras respuestas aquí resuelven este problema.
Spencer O'Reilly
75

Puede usar las propiedades window.innerWidth y window.innerHeight .

innerHeight vs externalHeight

CMS
fuente
29
Aunque esto no funciona en IE +1 para el diagrama: D. Para una pregunta como esta, debería ser un delito no tener más de estos.
allyourcode
8
@CMS document.documentElement.clientWidthes más preciso y más ampliamente compatible quewindow.innerWidth
ryanve
66
@ryanve Si por "más preciso" quieres decir "ni siquiera hace remotamente lo mismo", entonces sí: P
caja
Firefox Beta? Eso era algo que pertenecía al museo.
Derek 朕 會 功夫
@boxed En Safari móvil, document.documentElement.clientWidthme da el ancho de la ventana gráfica mientras que window.innerWidth me da el ancho del documento. Sí, por ahí.
John
33

Si no estás usando jQuery, se pone feo. Aquí hay un fragmento que debería funcionar en todos los navegadores nuevos. El comportamiento es diferente en modo Quirks y modo estándar en IE. Esto se encarga de eso.

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

var height = elem.clientHeight;
var width = elem.clientWidth;
Chetan Sastry
fuente
8
¿No te da esto el alto de la página, no la ventana gráfica? Eso es lo que parece indicar esta página: developer.mozilla.org/en/DOM/element.clientHeight
allyourcode
44
Está utilizando clientHeightel document.documentElementelemento, que le dará el tamaño de la ventana gráfica. Para obtener el tamaño del documento, debe hacerlo document.body.clientHeight. Como explica Chetan, este comportamiento se aplica a los navegadores modernos. Es fácil de probar. Simplemente abra una consola y escriba document.documentElement.clientHeightvarias pestañas abiertas.
Gajus
13

Sé que esto tiene una respuesta aceptable, pero me encontré con una situación en la clientWidthque no funcionó, ya que el iPhone (al menos el mío) devolvió 980, no 320, así que uséwindow.screen.width . Estaba trabajando en un sitio existente, me estaba haciendo "receptivo" y necesitaba forzar a los navegadores más grandes a usar una meta-vista diferente.

Espero que esto ayude a alguien, puede que no sea perfecto, pero funciona en mis pruebas en iOs y 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);
Llamativo
fuente
13

Miré y encontré una forma de navegador cruzado:

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>

usuario2921779
fuente
tenga en cuenta que el uso de un iframe de stackoverflow que rodea el fragmento de código confunde el resultado
Miller
11

Pude encontrar una respuesta definitiva en JavaScript: The Definitive Guide, 6th Edition by O'Reilly, p. 391:

Esta solución funciona incluso en modo Quirks, mientras que la solución actual de ryanve y ScottEvernden no.

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

}

excepto por el hecho de que me pregunto por qué la línea if (document.compatMode == "CSS1Compat")no es así if (d.compatMode == "CSS1Compat"), todo se ve bien.

nonopolaridad
fuente
¿Estás hablando de Retina display o Landscape vs Portrait o la etiqueta meta viewport? ¿No te refieres a píxeles virtuales como en snowdragonledhk.com/… ?
polaridad
1) Cuando hablo de pantallas de alto DPI me refiero a píxeles virtuales explicados aquí: stackoverflow.com/a/14325619/139361 . Cada pantalla de iPhone tiene exactamente 320 píxeles virtuales de ancho. 2) Digo que: a) documentElement.clientWidthno responde al cambio de orientación del dispositivo en iOS. b) muestra el recuento de píxeles físicos (prácticamente inútil) en lugar de píxeles virtuales
Dan
11

Si está buscando una solución que no sea jQuery que proporcione valores correctos en píxeles virtuales en dispositivos móviles , y cree que es simple window.innerHeighto document.documentElement.clientHeightpuede resolver su problema, estudie primero este enlace: https://tripleodeon.com/assets/2011/12/ table.html

El desarrollador ha realizado buenas pruebas que revelan el problema: puede obtener valores inesperados para Android / iOS, horizontal / vertical, pantallas normales / de alta densidad.

Mi respuesta actual aún no es una bala de plata (// todo), sino más bien una advertencia para aquellos que van a copiar y pegar rápidamente cualquier solución de este hilo en el código de producción.

Estaba buscando el ancho de página en píxeles virtuales en dispositivos móviles, y encontré que el único código de trabajo es (¡inesperadamente!) window.outerWidth. Más tarde examinaré esta tabla para encontrar la solución correcta que proporcione la altura, excluyendo la barra de navegación, cuando tenga tiempo.

Dan
fuente
10

Este código es 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: para leer el ancho, use console.log('viewport width'+viewport().width);

Xavier Blondel
fuente
9

Hay una diferencia entre window.innerHeighty document.documentElement.clientHeight. El primero incluye la altura de la barra de desplazamiento horizontal.

Szépe Viktor
fuente
1
¿Probó su respuesta en los sistemas operativos, en pantallas Retina y en modos horizontal / vertical? Este enlace cubre sistemas bastante desactualizados, pero demuestra que su código no funciona: tripleodeon.com/wp-content/uploads/2011/12/table.html
Dan
6

Una solución que se ajuste a los estándares W3C sería crear un div transparente (por ejemplo, dinámicamente con JavaScript), establecer su ancho y alto en 100vw / 100vh (unidades Viewport) y luego obtener su offsetWidth y offsetHeight. Después de eso, el elemento puede eliminarse nuevamente. Esto no funcionará en los navegadores más antiguos porque las unidades de la ventana gráfica son relativamente nuevas, pero si no le importan sino los estándares (que pronto serán), definitivamente podría ir de esta manera:

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);

Por supuesto, también puede establecer objNode.style.position = "fixed" y luego usar el 100% como ancho / alto; esto debería tener el mismo efecto y mejorar la compatibilidad hasta cierto punto. Además, establecer la posición en fijo podría ser una buena idea en general, porque de lo contrario el div será invisible pero consumirá algo de espacio, lo que provocará la aparición de barras de desplazamiento, etc.

Firefall
fuente
Desafortunadamente, la realidad destruye completamente su "W3C - solución de estándares": 1) caniuse.com/viewport-units , 2) caniuse.com/#feat=css-fixed . Lo que los desarrolladores necesitan es la solución que funcione, no "debería funcionar teóricamente".
Dan
Si podemos confiar en los estándares, entonces ni siquiera necesitamos todas esas soluciones de navegador cruzado. Una solución que responde a la especificación no es una solución.
Derek 朕 會 功夫
3

Así es como lo hago, lo probé en IE 8 -> 10, FF 35, Chrome 40, funcionará muy bien en todos los navegadores modernos (como se define window.innerWidth) y en IE 8 (sin ventana. innerWidth) también funciona sin problemas, cualquier problema (como parpadeo debido al desbordamiento: "oculto"), por favor repórtelo. No estoy realmente interesado en la altura de la ventana gráfica ya que hice esta función solo para solucionar algunas herramientas receptivas, pero podría implementarse. Espero que ayude, agradezco los comentarios y sugerencias.

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
fuente