Obtenga el ancho del dispositivo en javascript

128

¿Hay alguna manera de obtener el ancho del dispositivo de los usuarios, en lugar del ancho de la ventana gráfica, usando JavaScript?

Las consultas de medios CSS ofrecen esto, como puedo decir

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

y

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

Esto es útil si estoy apuntando a teléfonos inteligentes en orientación horizontal. Por ejemplo, en iOS, una declaración de max-width:640pxapuntará a los modos horizontal y vertical, incluso en un iPhone 4. Este no es el caso para Android, por lo que puedo decir, por lo que el uso del ancho del dispositivo en este caso apunta con éxito a ambas orientaciones, sin apuntar a dispositivos de escritorio.

Sin embargo , si invoco un enlace de JavaScript basado en el ancho del dispositivo, parece que estoy limitado a probar el ancho de la ventana gráfica, lo que significa una prueba adicional como en el siguiente,

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

Esto no me parece elegante, dado el indicio de que el ancho del dispositivo está disponible para css.

Nicholas Evans
fuente
44
Pruebe este sitio web para conocer las dimensiones correctas de su dispositivo. responsejs.com/labs/dimensions
Alpesh Darji
Modernizrpuede ayudarlo a hacer esto "de manera limpia y genérica": stackoverflow.com/questions/25935686/… . Con respecto al primer comentario: es posible que desee buscar en Google "Modernizr vs <otherLib> media query" para averiguar qué funciona mejor para su caso de uso
Adrien Be

Respuestas:

215

Puede obtener el ancho de pantalla del dispositivo a través de la propiedad screen.width.
A veces también es útil usar window.innerWidth (no se encuentra típicamente en dispositivos móviles) en lugar del ancho de la pantalla cuando se trata de navegadores de escritorio donde el tamaño de la ventana es a menudo menor que el tamaño de la pantalla del dispositivo.

Normalmente, cuando se trata de dispositivos móviles y navegadores de escritorio utilizo lo siguiente:

 var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
Bryan Rieger
fuente
55
Me di cuenta de que esto no funciona como se esperaba en el navegador nativo de Android 2.2. Si no estoy en una escala 1: 1, puede informar anchuras mucho más anchas (tan anchas como la página puede ser), lo cual es un poco frustrante.
Chris Bosco
44
Esto devuelve 980 en Chrome Beta en Android y 1024 en el navegador de Android en un HTC vívido.
Alex
44
@Alex Estos son los anchos de ventana de visualización predeterminados de los navegadores. Si usa una metaetiqueta de ventana gráfica, width=device-widthdebería obtener el valor real.
Brian Nickel
2
window.innerWidth está devolviendo 980 en Iphone (Chrome / Safari). ¿Como es eso? <meta name = "viewport" content = "width = device-width" /> no hizo ninguna diferencia.
Joao Leme
12
¿Cómo tiene esto tantos votos a favor? var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;devuelve 667 en iphone 6 y 6 Plus. Esta solución no funciona correctamente.
Ian S
60

Un problema con la útil respuesta de Bryan Rieger es que en las pantallas de alta densidad, los dispositivos Apple informan el ancho de la pantalla en dips, mientras que los dispositivos Android lo informan en píxeles físicos. (Ver http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html .) Sugiero usar if (window.matchMedia('(max-device-width: 960px)').matches) {}en navegadores compatibles con matchMedia.


fuente
1
Esto parece una solución mucho mejor y en realidad usa consultas de medios CSS. Me pregunto cuál es el soporte del navegador para esto en todas las plataformas móviles.
Carl Zulauf
1
¿Sería este el uso correcto? if (window.matchMedia('(max-device-width: 960px)').matches) { var winW = (window.innerWidth > 0) ? window.innerWidth : screen.width; } else { var winW = screen.width; }
norsewulf
3
No estoy seguro de si esto funcionará sin la escala establecida en 1: 1 como base ...var isMobile = window.matchMedia && window.matchMedia('(max-device-width: 960px)').matches || screen.width <= 960;
Tracker1
3
Para los navegadores que no soportan matchMedia()hay un polyfill: github.com/paulirish/matchMedia.js
AVL
44
Según caniuse.com, prácticamente todos los navegadores, incluidos los móviles, admiten window.matchMedia ()
Mark Langer el
14

Acabo de tener esta idea, así que tal vez sea miope, pero parece funcionar bien y podría ser la más consistente entre su CSS y JS.

En su CSS, establece el valor de ancho máximo para html en función del valor de pantalla @media:

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

    html { 
        max-width: 480px;
    }

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

}

Luego, usando JS (probablemente a través de un marco como JQuery), simplemente verificaría el valor de ancho máximo de la etiqueta html:

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

Ahora puede usar este valor para realizar cambios condicionales:

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

Si poner el valor de ancho máximo en la etiqueta html parece aterrador, entonces tal vez pueda colocar una etiqueta diferente, una que solo se use para este propósito. Para mi propósito, la etiqueta html funciona bien y no afecta mi marcado.


Útil si está utilizando Sass, etc .: para devolver un valor más abstracto, como el nombre del punto de interrupción, en lugar del valor de px, puede hacer algo como:

  1. Cree un elemento que almacene el nombre del punto de interrupción, p. Ej. <div id="breakpoint-indicator" />
  2. El uso de consultas de medios css cambia la propiedad de contenido para este elemento, por ejemplo, "grande" o "móvil", etc. (el mismo enfoque de consulta de medios básico que el anterior, pero configurando la propiedad 'contenido' de css en lugar de 'ancho máximo').
  3. Obtenga el valor de la propiedad de contenido CSS utilizando js o jquery (por ejemplo $('#breakpoint-indicator').css('content');, jquery ), que devuelve "grande" o "móvil", etc., dependiendo de la propiedad de contenido establecida por la consulta de medios.
  4. Actuar sobre el valor actual.

Ahora puede actuar sobre los mismos nombres de punto de interrupción que en sass, por ejemplo, sass: @include respond-to(xs)y js if ($breakpoint = "xs) {}.

Lo que más me gusta de esto es que puedo definir todos mis nombres de punto de interrupción en css y en un solo lugar (probablemente un documento scss de variables) y mi js puede actuar sobre ellos de forma independiente.

RogerRoger
fuente
8

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

Esto debería manejar la mayoría de los escenarios.

ZNS
fuente
Math.max (window.innerWidth); le dará el ancho, incluidas las barras de desplazamiento en Firefox, Edge y Chrome. document.documentElement.clientWidth; dará el ancho dentro de cualquier barra de desplazamiento en esos navegadores. En IE 11, ambos mostrarán el ancho, incluidas las barras de desplazamiento.
RationalRabbit
6

Deberías usar

document.documentElement.clientWidth

Se considera como compatibilidad entre navegadores, y es el mismo método que jQuery (window) .width (); usos.

Para obtener información detallada, consulte: https://ryanve.com/lab/dimensions/

FooBar
fuente
5

Creo que usar window.devicePixelRatioes más elegante que la window.matchMediasolución:

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

puedes usar fácilmente

document.documentElement.clientWidth

Reundo
fuente
3
En general, las respuestas son mucho más útiles si incluyen una explicación de lo que el código pretende hacer y por qué eso resuelve el problema sin introducir otros.
Tim Diekmann
3

Los teléfonos Lumia dan un ancho de pantalla incorrecto (al menos en el emulador). Entonces, ¿tal Math.min(window.innerWidth || Infinity, screen.width)vez funcionará en todos los dispositivos?

O algo más loco:

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

Ya puede usar document.documentElement.clientWidth para obtener el ancho del dispositivo del cliente y seguir el ancho del dispositivo mediante setInterval

al igual que

setInterval(function(){
        width = document.documentElement.clientWidth;
        console.log(width);
    }, 1000);
J. Pat
fuente
Solo usa onresize. Por ejemplo document.getElementsByTagName ("BODY") [0] .onresize = function ()
RationalRabbit
0

Al igual que para su información, hay una biblioteca llamada puntos de interrupción que detecta el ancho máximo establecido en CSS y le permite usarlo en condiciones JS if-else usando signos <=, <,>,> = y ==. Lo encontré bastante útil. El tamaño de la carga útil es inferior a 3 KB.

Abhishek Divekar
fuente