Como obter as dimensões da janela de visualização do navegador?

789

Desejo fornecer a meus visitantes a capacidade de ver imagens em alta qualidade. Existe alguma maneira de detectar o tamanho da janela?

Ou melhor ainda, o tamanho da janela de visualização do navegador com JavaScript? Veja a área verde aqui:

Alix Axel
fonte
10
O que faço é definir um elemento geralmente html para 100% de altura e obter sua altura. Trabalhos simples em qualquer lugar.
Muhammad Umer
1
@MuhammadUmer good catch! Se você ficar frustrado ao obter as dimensões (e, em celulares sem jQuery), poderá usar getComputedStylea htmltag expandida .
Dan
Além disso, você pode usar o W biblioteca, que lida com a detecção viewport cross-browser;)
pyrsmk

Respostas:

1328

Navegador cruzado @media (width) e @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 e .innerHeight

  • obtém viewport CSS @media (width) e @media (height)inclui barras de rolagem
  • initial-scalevariações de zoom e zoom podem fazer com que os valores móveis diminuam incorretamente para o que o PPK chama de viewport visual e sejam menores que os @mediavalores
  • o zoom pode fazer com que os valores sejam 1px desativados devido ao arredondamento nativo
  • undefined no IE8-

document.documentElement.clientWidth e .clientHeight

Recursos

ryanve
fonte
4
@ 01100001 Substitua $por verge. Se você deseja integrar ao jQuery, faça jQuery.extend(verge). Veja: verge.airve.com/#static
ryanve
4
Só queria mencionar que no IE8 (e talvez outros) você deve ter o <!DOCTYPE html>na parte superior da página para que o código funcione.
Tzury Bar Yochay
6
Eu não estou feliz com clientWidth / Altura em dispositivos móveis, realmente tripleodeon.com/wp-content/uploads/2011/12/table.html
Dan
24
A menos que esteja faltando alguma coisa, esta resposta está errada. No Chrome, pelo menos, document.documentElement.clientHeightretorna a altura da página , enquanto window.innerHeightretorna a altura da janela de exibição . Grande diferença.
Nate
2
diferentes variáveis de tamanho de tela / soluções ao vivo teste: ryanve.com/lab/dimensions
Alex Pandrea
106

Funções de dimensão jQuery

$(window).width() e $(window).height()

Scott Evernden
fonte
60
@allourcode, impossível, jQuery é a resposta para todos .
Xeoncross
21
Isso não obtém o tamanho da porta de visualização, mas o tamanho geral do documento. Tente.
Alejandro García Iglesias
2
Para navegadores que exibem suas barras de ferramentas complementares como HTML com publicação fixa, esta solução não está funcionando, especialmente se você deseja usar no posicionamento e nas porcentagens de posicionamento superior do código.
Adib Aroui
7
@AlejandroIglesias: Não, eu apenas testei nesta página do SO. $(window).height();retorna 536, enquanto $("html").height();retorna 10599
Flimm
2
Aviso: essas dimensões não incluem barras de rolagem (que têm tamanhos diferentes em diferentes navegadores e plataformas) e, portanto, não serão compatíveis com consultas de mídia css. Outras respostas aqui, no entanto, resolvem esse problema.
Spencer O'Reilly
75

Você pode usar os window.innerWidth e window.innerHeight propriedades.

innerHeight vs outerHeight

CMS
fonte
29
Mesmo que isso não funcione no IE +1 para o diagrama: D. Para uma pergunta como essa, deve ser um crime não ter mais.
Allyourcode
8
O @CMS document.documentElement.clientWidthé mais preciso e tem mais suporte do quewindow.innerWidth
ryanve
6
@ryanve Se por "mais preciso" você quer dizer "nem remotamente faz a mesma coisa", então sim: P
caixa
Firefox Beta? Isso é algo que pertenceu ao museu.
precisa
@boxed No Safari móvel, document.documentElement.clientWidthfornece a largura da janela de visualização, enquanto window.innerWidth fornece a largura do documento. Sim, dessa maneira.
John John
33

Se você não estiver usando o jQuery, ficará feio. Aqui está um trecho que deve funcionar em todos os novos navegadores. O comportamento é diferente no modo Quirks e no modo padrões no IE. Isso cuida disso.

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

var height = elem.clientHeight;
var width = elem.clientWidth;
Chetan Sastry
fonte
8
Isso não fornece a altura da página, não a janela de exibição? É o que esta página parece indicar: developer.mozilla.org/en/DOM/element.clientHeight
allyourcode
4
Você está usando clientHeighto document.documentElementelemento, que fornecerá o tamanho da viewport. Para obter o tamanho do documento, você precisaria document.body.clientHeight. Como explica Chetan, esse comportamento se aplica aos navegadores modernos. É fácil de testar. Basta abrir um console e digitar document.documentElement.clientHeightem várias guias abertas.
Gajus
13

Sei que essa resposta é aceitável, mas tive uma situação em que clientWidth que não funcionava, pois o iPhone (pelo menos o meu) retornava 980, não 320, então usei window.screen.width. Eu estava trabalhando no site existente, sendo "responsivo" e necessário forçar navegadores maiores a usar uma meta-viewport diferente.

Espero que isso ajude alguém, pode não ser perfeito, mas funciona nos meus testes em iOs e 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
fonte
13

Procurei e encontrei uma maneira 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>

user2921779
fonte
Nota O uso desse stackoverflow de um iframe em torno das messes trecho de código até o resultado
Miller
11

Consegui encontrar uma resposta definitiva em JavaScript: The Definitive Guide, 6th Edition by O'Reilly, p. 391:

Essa solução funciona mesmo no modo Quirks, enquanto a solução atual de ryanve e ScottEvernden não.

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

}

exceto pelo fato de eu me perguntar por que a linha if (document.compatMode == "CSS1Compat")não está if (d.compatMode == "CSS1Compat"), tudo parece bom.

falta de polaridade
fonte
você está falando sobre a tela Retina ou Paisagem versus Retrato ou a tag meta viewport? Você não quer dizer pixels virtuais como em snowdragonledhk.com/… ?
nonopolarity
1) Ao falar sobre telas de alto DPI, quero dizer pixels virtuais explicados aqui: stackoverflow.com/a/14325619/139361 . Cada tela do iPhone tem exatamente 320 pixels virtuais de largura. 2) Eu digo que: a) documentElement.clientWidthnão responde à alteração da orientação do dispositivo no iOS. b) exibe contar pixels físicos (praticamente inútil) em vez de pixels virtuais
Dan
11

Se você está procurando uma solução que não seja o jQuery, que fornece valores corretos em pixels virtuais no celular , e você acha isso simples window.innerHeightou document.documentElement.clientHeightpode resolver seu problema, estude este link primeiro: https://tripleodeon.com/assets/2011/12/ table.html

O desenvolvedor fez um bom teste que revela o problema: você pode obter valores inesperados para Android / iOS, paisagem / retrato, telas normais / de alta densidade.

Minha resposta atual ainda não é uma bala de prata (// todo), mas sim um aviso para aqueles que vão copiar e colar rapidamente qualquer solução desse segmento no código de produção.

Eu estava procurando a largura da página em pixels virtuais no celular e descobri que o único código que funciona é (inesperadamente!) window.outerWidth. Mais tarde, examinarei esta tabela para obter a solução correta, indicando a altura, excluindo a barra de navegação, quando tiver tempo.

Dan
fonte
10

Este código é 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 ler a largura, use console.log('viewport width'+viewport().width);

Xavier Blondel
fonte
9

Há uma diferença entre window.innerHeighte document.documentElement.clientHeight. O primeiro inclui a altura da barra de rolagem horizontal.

Szépe Viktor
fonte
1
Você testou sua resposta em sistemas operacionais, em telas Retina e nos modos paisagem / retrato? Esta ligação abrange os sistemas em vez ultrapassado, mas isso prova que o seu código não funciona: tripleodeon.com/wp-content/uploads/2011/12/table.html
Dan
6

Uma solução que estivesse em conformidade com os padrões W3C seria criar uma div transparente (por exemplo, dinamicamente com JavaScript), definir sua largura e altura para 100vw / 100vh (unidades de viewport) e obter seu offsetWidth e offsetHeight. Depois disso, o elemento pode ser removido novamente. Isso não funcionará em navegadores mais antigos, porque as unidades de viewport são relativamente novas, mas se você não se importa com elas, mas com os padrões (em breve), você pode definitivamente seguir este caminho:

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

Obviamente, você também pode definir objNode.style.position = "fixed" e usar 100% como largura / altura - isso deve ter o mesmo efeito e melhorar a compatibilidade em certa medida. Além disso, definir a posição como fixa pode ser uma boa ideia em geral, porque, caso contrário, a div ficará invisível, mas consumirá algum espaço, o que levará a barras de rolagem aparecendo etc.

Firefall
fonte
Infelizmente, a realidade destrói completamente a sua "solução de padrões W3C": 1) caniuse.com/viewport-units , 2) caniuse.com/#feat=css-fixed . O que os desenvolvedores precisam é da solução que funciona, e não "deveria teoricamente funcionar".
Dan
Se podemos confiar nos padrões, nem precisamos de todas essas soluções entre navegadores. Uma solução que responde às especificações não é uma solução.
Derek #
3

É assim que eu faço, tentei no IE 8 -> 10, FF 35, Chrome 40, funcionará muito bem em todos os navegadores modernos (como window.innerWidth está definido) e no IE 8 (sem janela). innerWidth) também funciona bem, qualquer problema (como piscar por causa do estouro: "oculto"), informe-o. Não estou realmente interessado na altura da janela de exibição, pois fiz essa função apenas para solucionar algumas ferramentas responsivas, mas ela pode ser implementada. Espero que ajude, agradeço comentários e sugestões.

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
fonte