cross-browser title - Obtenga las dimensiones del visor del navegador con JavaScript




tag html5 (11)

Valores de @media (width) y @media (height) del navegador cruzado

var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

window.innerWidth y .innerHeight

  • obtiene CSS viewport @media (width) y @media (height) que incluyen barras de desplazamiento
  • initial-scale variations initial-scale y zoom pueden hacer que los valores móviles se reduzcan de manera errónea a lo que PPK denomina vista gráfica visual y sean más pequeños que los valores de @media
  • el zoom puede provocar que los valores estén desactivados en 1px debido al redondeo nativo
  • undefined en IE8-

document.documentElement.clientWidth y .clientHeight

Recursos

Quiero proporcionar a mis visitantes la posibilidad 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 del visor del navegador con JavaScript? Ver área verde aquí:


Una solución que se ajustaría a los estándares de 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 offsetWidth y offsetHeight. Después de eso, el elemento puede ser eliminado de nuevo. Esto no funcionará en los navegadores más antiguos porque las unidades de la ventana gráfica son relativamente nuevas, pero si no te interesan por ellas, sino por los estándares (que pronto serán), definitivamente podrías 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 = "arreglado" y luego usar 100% como ancho / alto. Esto debería tener el mismo efecto y mejorar la compatibilidad en cierta medida. Además, establecer la posición a fijo puede ser una buena idea en general, porque de lo contrario el div será invisible pero consumirá algo de espacio, lo que hará que aparezcan barras de desplazamiento, etc.


Si está buscando una solución que no sea jQuery que ofrezca los valores correctos en píxeles virtuales en dispositivos móviles y cree que plain window.innerHeight o document.documentElement.clientHeight puede resolver su problema, estudie este enlace primero: tripleodeon.com/wp-content/uploads/2011/12/table.html

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

Mi respuesta actual no es aún una bala de plata (// todo), sino más bien una advertencia para aquellos que van a copiar y pegar rápidamente cualquier solución dada 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 que funciona es (inesperadamente) window.outerWidth . Más adelante, examinaré esta tabla para encontrar la solución correcta, con la altura excluyendo la barra de navegación, cuando tenga tiempo.


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

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

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 if (d.compatMode == "CSS1Compat") , todo se ve bien.



Sé que esto tiene una respuesta aceptable, pero me encontré con una situación en la que clientWidth no funcionaba, ya que el iPhone (al menos el mío) devolvió 980, no 320, así que utilicé window.screen.width . Estaba trabajando en el sitio existente, me hice "sensible" y necesitaba forzar a los navegadores más grandes a usar un meta-viewport 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);

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


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 a un desbordamiento: "oculto"), infórmelo. No estoy realmente interesado en la altura de la ventana gráfica, ya que hice esta función solo para solucionar algunas herramientas sensibles, pero podría estar implementada. 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)
  );
}

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

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

var height = elem.clientHeight;
var width = elem.clientWidth;

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


Aquí está mi solución. Primero va algún objeto de utilidad para trabajar con cookie.

/* Simple getter and setter for cookies */
(function(global){
    function setCookie(cname, cvalue, exdays) {
        exdays = typeof exdays === 'undefined' && 365;

        var d = new Date();
        d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
        var expires = "expires="+d.toUTCString();
        document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
    }

    function getCookie(cname) {
        var name = cname + "=";
        var ca = document.cookie.split(';');
        for(var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') {
                c = c.substring(1);
            }
            if (c.indexOf(name) == 0) {
                return c.substring(name.length, c.length);
            }
        }
        return undefined;
    }

    global.Cookie = {
        get: getCookie,
        set: setCookie
    };
})(window);

Entonces puedes hacer algo como ...

/* 
  Detect screen width and height and save it to a cookie.
  We are later using it to resize the images accordingly.
*/
if(
    !Cookie.get('screen_width') ||
    !Cookie.get('screen_height') ||
    Cookie.get('screen_width') != screen.width ||
    Cookie.get('screen_height') != screen.height
  ){
  Cookie.set('screen_width', screen.width);
  Cookie.set('screen_height', screen.height);
  location.reload();
}

De esta manera, puede utilizar un idioma del lado del servidor para leer las cookies y obtener el tamaño de imagen exacto de la pantalla del usuario.





javascript cross-browser viewport