Obter a largura do dispositivo em javascript

128

Existe uma maneira de obter a largura do dispositivo dos usuários, em oposição à largura da porta de visualização, usando javascript?

As consultas de mídia CSS oferecem isso, como posso dizer

@media screen and (max-width:640px) {
    /* ... */
}

e

@media screen and (max-device-width:960px) {
    /* ... */
}

Isso é útil se eu estiver segmentando smartphones na orientação paisagem. Por exemplo, no iOS, uma declaração de max-width:640pxsegmentará os modos paisagem e retrato, mesmo em um iPhone 4. Esse não é o caso do Android, pelo que sei, portanto, usar a largura do dispositivo nessa instância visa com êxito ambas as orientações, sem segmentar dispositivos de desktop.

No entanto , se estou chamando uma ligação javascript com base na largura do dispositivo, pareço estar limitado a testar a largura da janela de visualização, o que significa um teste extra, como a seguir,

if ($(window).width() <= 960 && $(window).height <= 640) { /* ... */ }

Isso não me parece elegante, dada a dica de que a largura do dispositivo está disponível para css.

Nicholas Evans
fonte
4
Experimente este site para conhecer as dimensões corretas do seu dispositivo. responsejs.com/labs/dimensions
Alpesh Darji
Modernizrpode ajudá-lo a fazer isso "da maneira limpa e genérica": stackoverflow.com/questions/25935686/… . Em relação ao 1º comentário: você pode querer google "Modernizr vs <otherLib> consulta de mídia" para descobrir o que funciona melhor para o seu caso de uso
Adrien Seja

Respostas:

215

Você pode obter a largura da tela do dispositivo através da propriedade screen.width.
Às vezes, também é útil usar window.innerWidth (normalmente não encontrado em dispositivos móveis) em vez da largura da tela ao lidar com navegadores de desktop em que o tamanho da janela geralmente é menor que o tamanho da tela do dispositivo.

Normalmente, ao lidar com dispositivos móveis E navegadores de desktop, uso o seguinte:

 var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
Bryan Rieger
fonte
5
Percebi que isso não funciona conforme o esperado no navegador nativo do Android 2.2. Se não estou em uma escala de 1: 1, ele pode reportar larguras muito mais amplas (a largura da página), o que é um pouco frustrante.
21711 Chris Bosco
4
Isso retorna 980 no Chrome Beta no Android e 1024 no navegador Android em um HTC vivid.
23412 Alex
4
@Alex Essas são as larguras de janela de exibição padrão dos navegadores. Se você usar uma meta tag de viewport, width=device-widthdeverá obter o valor real.
Brian Nickel
2
window.innerWidth está retornando 980 no Iphone (Chrome / Safari). Como é isso? <meta name = "viewport" content = "width = device-width" /> não fez diferença.
João Leme
12
Como isso tem tantos votos positivos? var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;retorna 667 no iphone 6 e 6 mais. Esta solução não funciona corretamente.
Ian S
60

Um problema com a resposta útil de Bryan Rieger é que, em telas de alta densidade, os dispositivos Apple relatam screen.width em mergulhos, enquanto os dispositivos Android relatam em pixels físicos. (Consulte http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html .) Sugiro usar if (window.matchMedia('(max-device-width: 960px)').matches) {}em navegadores compatíveis com matchMedia.


fonte
1
Parece uma solução muito melhor e, na verdade, usa consultas de mídia CSS. Gostaria de saber qual é o suporte do navegador para isso nas plataformas móveis?
precisa saber é o seguinte
1
Esse seria o uso correto? if (window.matchMedia('(max-device-width: 960px)').matches) { var winW = (window.innerWidth > 0) ? window.innerWidth : screen.width; } else { var winW = screen.width; }
Norsewulf
3
Eu não tenho certeza se isso vai funcionar sem o conjunto de escala para 1: 1 como uma base ...var isMobile = window.matchMedia && window.matchMedia('(max-device-width: 960px)').matches || screen.width <= 960;
Tracker1
3
Para navegadores que não suportam, matchMedia()existe um polyfill: github.com/paulirish/matchMedia.js
AvL
4
De acordo com caniuse.com praticamente todos os navegadores, incluindo móvel, suporte window.matchMedia ()
Mark Langer
14

Eu apenas tive essa idéia, talvez seja míope, mas parece funcionar bem e pode ser a mais consistente entre seu CSS e JS.

No seu CSS, você define o valor da largura máxima para html com base no valor da tela @media:

@media screen and (max-width: 480px) and (orientation: portrait){

    html { 
        max-width: 480px;
    }

    ... more styles for max-width 480px screens go here

}

Então, usando JS (provavelmente por meio de uma estrutura como JQuery), basta verificar o valor da largura máxima da tag html:

maxwidth = $('html').css('max-width');

Agora você pode usar esse valor para fazer alterações condicionais:

If (maxwidth == '480px') { do something }

Se colocar o valor de largura máxima na tag html parecer assustador, talvez você possa colocar uma tag diferente, que seja usada apenas para esse fim. Para meu propósito, a tag html funciona bem e não afeta minha marcação.


Útil se você estiver usando Sass, etc : Para retornar um valor mais abstrato, como o nome do ponto de interrupção, em vez do valor de px, você pode fazer algo como:

  1. Crie um elemento que armazene o nome do ponto de interrupção, por exemplo <div id="breakpoint-indicator" />
  2. O uso de consultas de mídia css altera a propriedade de conteúdo desse elemento, por exemplo, "grande" ou "móvel", etc. (a mesma abordagem básica de consulta de mídia acima, mas definindo a propriedade 'conteúdo' do css em vez de 'largura máxima').
  3. Obtenha o valor da propriedade de conteúdo css usando js ou jquery (jquery, por exemplo $('#breakpoint-indicator').css('content');), que retorna "grande" ou "móvel" etc., dependendo de como a propriedade de conteúdo é definida pela consulta de mídia.
  4. Atue no valor atual.

Agora você pode agir com os mesmos nomes de ponto de interrupção que você faz no sass, por exemplo, sass: @include respond-to(xs)e js if ($breakpoint = "xs) {}.

O que mais gosto sobre isso é que posso definir todos os nomes dos pontos de interrupção em css e em um único local (provavelmente um documento scss de variáveis) e meus js podem atuar neles independentemente.

Entendido
fonte
8

var width = Math.max(window.screen.width, window.innerWidth);

Isso deve lidar com a maioria dos cenários.

ZNS
fonte
Math.max (window.innerWidth); fornecerá a largura, incluindo barras de rolagem no FireFox, Edge e Chrome. document.documentElement.clientWidth; dará a largura dentro de qualquer barra de rolagem nesses navegadores. No IE 11, ambos mostrarão a largura, incluindo barras de rolagem.
RationalRabbit
6

Você deveria usar

document.documentElement.clientWidth

É considerado compabilidade entre navegadores e é o mesmo método que jQuery (window) .width (); usos.

Para informações detalhadas, consulte: https://ryanve.com/lab/dimensions/

FooBar
fonte
5

Eu acho que usar window.devicePixelRatioé mais elegante que a window.matchMediasolução:

if (window.innerWidth*window.devicePixelRatio <= 960 
    && window.innerHeight*window.devicePixelRatio <= 640) { 
    ... 
}
maxime schoeni
fonte
5

você pode facilmente usar

document.documentElement.clientWidth

Reundo
fonte
3
Geralmente, as respostas são muito mais úteis se incluem uma explicação sobre o que o código pretende fazer e por que isso resolve o problema sem a introdução de outros.
Tim Diekmann
3

Os telefones Lumia oferecem largura de tela incorreta (pelo menos no emulador). Então, talvez Math.min(window.innerWidth || Infinity, screen.width)funcione em todos os dispositivos?

Ou algo mais louco:

for (var i = 100; !window.matchMedia('(max-device-width: ' + i + 'px)').matches; i++) {}
var deviceWidth = i;
Munawwar
fonte
2

Sim, você pode usar document.documentElement.clientWidth para obter a largura do dispositivo do cliente e acompanhar a largura do dispositivo, colocando setInterval

Assim como

setInterval(function(){
        width = document.documentElement.clientWidth;
        console.log(width);
    }, 1000);
J. Pat
fonte
Basta usar o redimensionamento. Por exemplo, document.getElementsByTagName ("BODY") [0] .onresize = function ()
RationalRabbit
0

Assim como um FYI, existe uma biblioteca chamada pontos de interrupção, que detecta a largura máxima conforme definida em CSS e permite que você a use em condições JS se-else usando sinais <=, <,>,> = e ==. Achei bastante útil. O tamanho da carga útil é inferior a 3 KB.

Abhishek Divekar
fonte