Detectar un navegador móvil

889

Estoy buscando una función que devuelva un valor booleano si el usuario tiene un navegador móvil o no.

Sé que puedo usar navigator.userAgenty escribir esa función usando regex, pero los agentes de usuario son demasiado diferentes para diferentes plataformas. Dudo que coincida con todos los dispositivos posibles sería fácil, y creo que este problema se ha resuelto antes muchas veces, por lo que debería haber algún tipo de solución completa para dicha tarea.

Estaba mirando este sitio , pero lamentablemente el script es tan críptico que no tengo idea de cómo usarlo para mi propósito, que es crear una función que devuelva verdadero / falso.

Cra
fuente
66
Relacionado: stackoverflow.com/questions/3514784/… .
Frédéric Hamidi
2
Intenta leer esto. stackoverflow.com/questions/743129/…
KyelJmD
55
@Thrustmaster: Realmente no lo haría. Servir diferentes JS a diferentes navegadores significa que debe agregar Vary: User-Agenta su respuesta, de lo contrario, los servidores proxy de almacenamiento en caché almacenarán una versión y la enviarán al otro tipo de navegador. Pero Vary: User-Agenthace que la respuesta no se pueda localizar en IE.
bobince
17
@ave: ¿Qué intentas hacer al detectar un navegador "móvil"? La distinción es muy discutible en el mundo actual de las tabletas y los dispositivos informáticos híbridos. ¿Está buscando detectar pantallas pequeñas y presentar una IU diferente en ese caso? ¿Estás buscando detectar conectividad de bajo ancho de banda? ¿Estás buscando detectar interfaces táctiles?
bobince
2
Así que actualicé mi respuesta para usar el método de Javascript detectmobilebrowsers.com pero devuelvo un valor booleano si alguien aún necesita esto. ( por si acaso ). Detección feliz :)
Michael Zaporozhets

Respuestas:

1318

Usando Regex (de detectmobilebrowsers.com ):

Aquí hay una función que utiliza una expresión regular increíblemente larga y completa que devuelve un valor trueo falsedependiendo de si el usuario está navegando o no con un dispositivo móvil.

window.mobileCheck = function() {
  let check = false;
  (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
  return check;
};

Para aquellos que deseen incluir tabletas en esta prueba (aunque podría decirse que no deberían), pueden usar la siguiente función:

window.mobileAndTabletCheck = function() {
  let check = false;
  (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
  return check;
};

La respuesta original

Puede hacer esto simplemente ejecutando una lista de dispositivos y comprobando si useragentcoincide con algo así:

  function detectMob() {
    const toMatch = [
        /Android/i,
        /webOS/i,
        /iPhone/i,
        /iPad/i,
        /iPod/i,
        /BlackBerry/i,
        /Windows Phone/i
    ];

    return toMatch.some((toMatchItem) => {
        return navigator.userAgent.match(toMatchItem);
    });
}

Sin embargo, dado que cree que este método no es confiable, podría suponer que cualquier dispositivo que tuviera una resolución de 800x600 o menos también era un dispositivo móvil, lo que limita aún más su objetivo (aunque en la actualidad muchos dispositivos móviles tienen resoluciones mucho mayores que esta)

es decir

  function detectMob() {
    return ( ( window.innerWidth <= 800 ) && ( window.innerHeight <= 600 ) );
  }

Referencia:

Michael Zaporozhets
fuente
25
Hola, acabo de visitar el enlace detectmobilebrowsers.com en mi iPad 3, iOS 6.1.2, y dice "No se detectó ningún navegador móvil".
Richard Lovejoy
49
@RichardLovejoy al construir sitios, el ipad generalmente no se considera un dispositivo móvil.
Michael Zaporozhets
42
Desde la página Acerca de : tabletas de Android, iPads, Kindle Fires y PlayBooks no se detectan por diseño. Para agregar soporte para tabletas, agregue |android|ipad|playbook|silka la primera expresión regular.
Gras Double
13
Google TV también es Android. ¿Qué define a un móvil? Tamaño de pantalla ? Toque? dispositivo Orientación? Cuando diseño es más una cuestión de mousehover o no, gran botón o pequeños enlaces. Entonces, por ahora, corro con "if (Modernizr.touch)" :)
molokoloco
31
Gawd, toda esta idea de agentes de usuario es horrible y realmente, realmente tiene que parar. Realmente necesitamos dejar de permitir que los clientes luchen contra la corriente y simplemente seguir con las consultas de los medios. Si quieren hacer redirecciones basadas en la escala de páginas particulares, simplemente verifique el rango de una consulta de medios particular a través de JS, es decir, tylergaw.com/articles/reacting-to-media-queries-in-javascript
marksyzm
324

Qué tal si:

if (typeof window.orientation !== 'undefined') { ... }

... ya que los teléfonos inteligentes generalmente admiten esta propiedad y los navegadores de escritorio no.

EDITAR: Como señaló @Gajus, esta solución ahora está en desuso y no debe usarse ( https://developer.mozilla.org/en-US/docs/Web/API/Window/orientation )

yoav barnea
fuente
14
esto es realmente único e increíble, ¿te importa si lo agrego a mi respuesta?
Michael Zaporozhets
77
Esto probablemente no va a funcionar por mucho tiempo. 1) Las tabletas pueden tener tamaños de pantalla decentes, desea que muestren el sitio web de escritorio completo pero tendrán esta propiedad 2) Windows 8 está aquí y con él un montón de computadoras portátiles con pantalla táctil y pantallas que giran.
Dave Hilditch
10
en cuanto a su primer punto sobre Tabletas con tamaños de pantalla decentes: creo que también podría presentar los mismos argumentos para todas las demás soluciones (una tableta con pantalla grande que se rastrea como pantalla pequeña). de todos modos, la idea aquí es buscar propiedades que hayan sido compartidas por dispositivos pequeños en lugar de mantener un código largo de mantenimiento y agregar expresiones regulares con cada nuevo dispositivo / vesion / modelo. Creo que la detección de dispositivos pertenece al pasado y hoy debemos centrarnos en la detección de funciones. Una vez más, me alegrará aquí sobre propiedades más adecuadas para ese asunto ...
yoav barnea
2
Me encanta y funciona perfectamente, gracias. Para mi solución, estaba justo después de simple.
Bojangles
40
window.orientationes una propiedad en desuso ( developer.mozilla.org/en-US/docs/Web/API/Window/orientation , compat.spec.whatwg.org/#dom-window-orientation ) que algunos navegadores móviles eligen admitir por razones desconocidas . Implementación de los mismos navegadores window.screen.orientation(que también se define en los navegadores de escritorio). Solo puedo suponer que window.orientationse deja allí por razones heredadas y, por lo tanto, no se debe usar en nuevas aplicaciones.
Gajus
115
var isMobile = {
    Android: function() {
        return navigator.userAgent.match(/Android/i);
    },
    BlackBerry: function() {
        return navigator.userAgent.match(/BlackBerry/i);
    },
    iOS: function() {
        return navigator.userAgent.match(/iPhone|iPad|iPod/i);
    },
    Opera: function() {
        return navigator.userAgent.match(/Opera Mini/i);
    },
    Windows: function() {
        return navigator.userAgent.match(/IEMobile/i) || navigator.userAgent.match(/WPDesktop/i);
    },
    any: function() {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
};

Cómo utilizar

if( isMobile.any() ) alert('Mobile');

Para verificar si el usuario está en un dispositivo móvil específico:

if( isMobile.iOS() ) alert('iOS');

Ref: http://www.abeautifulsite.net/blog/2011/11/detecting-mobile-devices-with-javascript

Versión mejorada en github: https://github.com/smali-kazmi/detect-mobile-browser

Mudaser Ali
fuente
¿Por qué no hacer any()un for ... en bucle de isMobilemiembros ORed ?
SomeShinyObject 01 de
@ChristopherW Creé su complemento y el código modificado como me aconsejaste
Mudaser Ali
2
¿Tal vez mover iOS por delante de BlackBerry () solo para poner los casos más comunes primero y dejar que el rescate anticipado ahorre un poco de procesamiento adicional?
Rob_vH
2
@Rob_vH había puesto este código en github ( github.com/smali-kazmi/detect-mobile-browser ) con algunas características avanzadas; estás abierto a enviar sugerencias allí también
Mudaser Ali
1
@AkarshSatija ¿La caída del rendimiento de esas 5 comprobaciones de expresiones regulares en realidad afecta a alguna de sus aplicaciones? Me sorprendería mucho si lo hiciera. La optimización prematura puede ser una pérdida de tiempo ...
trusktr
68

Aquí hay una solución simple de la fuente del tirachinas de Facebook

var isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
if (isMobile) {
  /* your code here */
}
Santhosh
fuente
Agradable. Muy útil en ciertas situaciones
Chuck Le Butt
Útil para el caso de detectar un dispositivo donde podría instalarse una aplicación móvil. No te importa el navegador, per se. Solo el dispositivo / SO.
Charlie Reitzel
31

Vine aquí buscando una manera simple y limpia de detectar "dispositivos de pantallas táctiles", que clasifico como móviles y tabletas. No encontré una opción limpia en las respuestas actuales, pero resolvió lo siguiente que también puede ayudar a alguien.

var touchDevice = ('ontouchstart' in document.documentElement);

Editar : para admitir escritorios con pantalla táctil y móviles al mismo tiempo, puede usar lo siguiente:

var touchDevice = (navigator.maxTouchPoints || 'ontouchstart' in document.documentElement);
Tigger
fuente
99
¿Qué pasa si el monitor de escritorio admite el tacto?
Anton Kuzmin
@HappyCoder Creo que depende del sistema operativo decirle al navegador cuando la pantalla táctil de un escritorio está activa. Entonces, sí, esta verificación aún debería ser válida.
Tigger
(+1), sin embargo, mi escritorio que estoy usando ahora tiene una pantalla táctil, y no siempre es consistente touchstart|end|etc.
Cody
1
Bootstrap datepicker utiliza lo siguiente: if (window.navigator.msMaxTouchPoints || 'ontouchstart' en el documento) {this.input.blur (); }
JT Taylor
1
@JTTaylor Parece que Microsoft está recomendando navigator.maxTouchPoints (sin msprefijo). También hay un artículo de MDN para verificar.
Tigger
20

Como muchos han dicho, confiar en el objetivo móvil de los datos del agente de usuario es problemático. Lo mismo se puede decir para contar con el tamaño de la pantalla.

Mi enfoque está tomado de una técnica CSS para determinar si la interfaz es táctil:

Usando solo javascript (compatible con todos los navegadores modernos), una coincidencia de consulta de medios puede inferir fácilmente si el dispositivo es móvil .

function isMobile() {
    var match = window.matchMedia || window.msMatchMedia;
    if(match) {
        var mq = match("(pointer:coarse)");
        return mq.matches;
    }
    return false;
}
gsxrboy73
fuente
66
¿Qué pasa con las computadoras portátiles con pantallas táctiles habilitadas?
Maxim
66
Yo buscaría! MatchMedia ("(any-pointer: fine)"). Coincide conmigo mismo. ("No se conectó el mouse", en lugar de "tiene una pantalla táctil".
Sora2455
Esto funciona mientras que mi último guión sería engañado por personas que usan la función de zoom del navegador (por ejemplo, un tipo con el que estaba hablando en una pantalla de 13 "con 4K que bajó a 1080p y todavía tuvo que usar el zoom). Trabajó en mi iPhone (Safari / Firefox) y dispositivos Android (Waterfox / Chrome / "Browser"). Definitivamente mucho más confiable que todas las respuestas más votadas.
John
no detecta FireFox fennec en un Android para el que completé con navigator.userAgent.toLowerCase (). indexOf ('fennec')> -1 (quizás no sea el mejor suplemento ..)
StayCool
2
Además, puede probar la propiedad de desplazamiento: para teléfonos inteligentes y pantallas táctiles @media (desplazamiento: ninguno) y (puntero: grueso)
Batailley
16

Según el artículo de MDN sobre la detección del navegador utilizando el agente de usuario , se recomienda evitar este enfoque si es posible y sugerir otras vías, como la detección de funciones.

Sin embargo, si uno debe usar el agente de usuario como un medio para detectar si el dispositivo es móvil, sugieren:

En resumen, recomendamos buscar la cadena "Mobi" en cualquier parte del Agente de usuario para detectar un dispositivo móvil.

Por lo tanto, este one-liner será suficiente:

const isMobileDevice = window.navigator.userAgent.toLowerCase().includes("mobi");

[ACTUALIZAR]:

Como @ zenw0lf sugiere en los comentarios, usar una expresión regular sería mejor:

const isMobileDevice = /Mobi/i.test(window.navigator.userAgent)

TheDarkIn1978
fuente
.includesno soportado por IE-11
Pasha Oleynik
1
@PashaOleynik un polyfill puede arreglar eso
Maxim
La tableta Nexus 7 con Android no tiene Mobileuna cadena de agente de usuario
Alex Sorokoletov
@AlexSorokoletov También para el artículo de MDNIf the device is large enough that it's not marked with “Mobi”, you should serve your desktop site (which, as a best practice, should support touch input anyway, as more desktop machines are appearing with touchscreens).
TheDarkIn1978
1
Creo que esto funcionaría en cualquier lugar sin polyfills: const isMobile = /Mobi/.test(window.navigator.userAgent)
zenw0lf
14

No existe una solución perfecta para detectar si el código JS se ejecuta en un navegador móvil, pero las siguientes dos opciones deberían funcionar en la mayoría de los casos.

Opción 1: rastreo del navegador

!function(a){var b=/iPhone/i,c=/iPod/i,d=/iPad/i,e=/(?=.*\bAndroid\b)(?=.*\bMobile\b)/i,f=/Android/i,g=/(?=.*\bAndroid\b)(?=.*\bSD4930UR\b)/i,h=/(?=.*\bAndroid\b)(?=.*\b(?:KFOT|KFTT|KFJWI|KFJWA|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|KFARWI|KFASWI|KFSAWI|KFSAWA)\b)/i,i=/IEMobile/i,j=/(?=.*\bWindows\b)(?=.*\bARM\b)/i,k=/BlackBerry/i,l=/BB10/i,m=/Opera Mini/i,n=/(CriOS|Chrome)(?=.*\bMobile\b)/i,o=/(?=.*\bFirefox\b)(?=.*\bMobile\b)/i,p=new RegExp("(?:Nexus 7|BNTV250|Kindle Fire|Silk|GT-P1000)","i"),q=function(a,b){return a.test(b)},r=function(a){var r=a||navigator.userAgent,s=r.split("[FBAN");return"undefined"!=typeof s[1]&&(r=s[0]),s=r.split("Twitter"),"undefined"!=typeof s[1]&&(r=s[0]),this.apple={phone:q(b,r),ipod:q(c,r),tablet:!q(b,r)&&q(d,r),device:q(b,r)||q(c,r)||q(d,r)},this.amazon={phone:q(g,r),tablet:!q(g,r)&&q(h,r),device:q(g,r)||q(h,r)},this.android={phone:q(g,r)||q(e,r),tablet:!q(g,r)&&!q(e,r)&&(q(h,r)||q(f,r)),device:q(g,r)||q(h,r)||q(e,r)||q(f,r)},this.windows={phone:q(i,r),tablet:q(j,r),device:q(i,r)||q(j,r)},this.other={blackberry:q(k,r),blackberry10:q(l,r),opera:q(m,r),firefox:q(o,r),chrome:q(n,r),device:q(k,r)||q(l,r)||q(m,r)||q(o,r)||q(n,r)},this.seven_inch=q(p,r),this.any=this.apple.device||this.android.device||this.windows.device||this.other.device||this.seven_inch,this.phone=this.apple.phone||this.android.phone||this.windows.phone,this.tablet=this.apple.tablet||this.android.tablet||this.windows.tablet,"undefined"==typeof window?this:void 0},s=function(){var a=new r;return a.Class=r,a};"undefined"!=typeof module&&module.exports&&"undefined"==typeof window?module.exports=r:"undefined"!=typeof module&&module.exports&&"undefined"!=typeof window?module.exports=s():"function"==typeof define&&define.amd?define("isMobile",[],a.isMobile=s()):a.isMobile=s()}(this);

alert(isMobile.any ? 'Mobile' : 'Not mobile');

Este código de rastreo particular del navegador es el de una biblioteca llamada isMobile .


Opción 2: ventana.orientación

Prueba si window.orientationestá definido:

var isMobile = window.orientation > -1;
alert(isMobile ? 'Mobile' : 'Not mobile');


Nota

No todos los dispositivos con pantalla táctil son móviles y viceversa. Entonces, si desea implementar algo específicamente para la pantalla táctil, no debe probar si su navegador se ejecuta en un dispositivo móvil, sino más bien si los dispositivos son compatibles con la pantalla táctil:

var hasTouchscreen = 'ontouchstart' in window;
alert(hasTouchscreen ? 'has touchscreen' : 'doesn\'t have touchscreen');

John Slegers
fuente
¡El enfoque de orientación es realmente agradable! ))
Maxim
1
Me gusta tu window.orientationsolución, pero los documentos dicen que está en desuso. developer.mozilla.org/en-US/docs/Web/API/Window/orientation
skwidbreth
3
El enfoque de orientación NO es bueno porque Windows 8 y superior pueden cambiar la orientación.
Heitor
Windows 8 y versiones posteriores se centran en agregar soporte para móviles, pero también híbridos (computadoras portátiles que pueden convertirse en almohadillas grandes), razón por la cual la orientación falla como método de detección, incluso si Moz no se refería a ella como obsoleta.
Jeff Clayton
Es de Win 7 con el software gráfico instalado. Puede cambiar la orientación, pero hágase una pregunta, ¿quién puede usar una computadora de escritorio / portátil con otra orientación de pantalla como Vertical en lugar de Horizontal y usar i durante más de 1 minuto? Ninguno !!! Cambiar la orientación en el escritorio significa que comenzará a leer los caracteres en la pantalla de abajo hacia arriba.
GirlCode
11

Aquí hay una solución de UserAgent que es más eficiente que la coincidencia ...

function _isMobile(){
    // if we want a more complete list use this: http://detectmobilebrowsers.com/
    // str.test() is more efficent than str.match()
    // remember str.test is case sensitive
    var isMobile = (/iphone|ipod|android|ie|blackberry|fennec/).test
         (navigator.userAgent.toLowerCase());
    return isMobile;
}
JeffJak
fuente
77
el método de prueba no distingue entre mayúsculas y minúsculas, pero su expresión regular sí lo es. puede marcar una expresión regular sin distinción entre mayúsculas y minúsculas con una "i" al final y hacer/iphone|etc/i.test(navigator.userAgent)
xec
11

Para agregar una capa adicional de control, uso el almacenamiento HTML5 para detectar si está usando almacenamiento móvil o almacenamiento de escritorio. Si el navegador no admite almacenamiento, tengo una matriz de nombres de navegador móvil y comparo el agente de usuario con los navegadores de la matriz.

Es bastante simple Aquí está la función:

// Used to detect whether the users browser is an mobile browser
function isMobile() {
    ///<summary>Detecting whether the browser is a mobile browser or desktop browser</summary>
    ///<returns>A boolean value indicating whether the browser is a mobile browser or not</returns>

    if (sessionStorage.desktop) // desktop storage 
        return false;
    else if (localStorage.mobile) // mobile storage
        return true;

    // alternative
    var mobile = ['iphone','ipad','android','blackberry','nokia','opera mini','windows mobile','windows phone','iemobile']; 
    for (var i in mobile) if (navigator.userAgent.toLowerCase().indexOf(mobile[i].toLowerCase()) > 0) return true;

    // nothing found.. assume desktop
    return false;
}
Rasmus Søborg
fuente
3
Todavía no lo he probado en dispositivos móviles, pero sessionStorage.desktopno existe en Safari, Chrome o Firefox (todas las versiones más recientes en el momento de la publicación). Sin embargo, obtiene un voto positivo, ya que su solución va en una mejor dirección que otras. Pero no olvides usar en var mobile =lugar de mobile =.
Shuckster
3
También es una buena idea no usar indexOf con navegadores más antiguos que todavía no son compatibles con ese método, o usar un polyfill. No es necesario usar toLowerCase en una lista de valores en minúsculas, ni es necesario hacerlo si está ejecutando /ipad|iphone|etc/i.test(navigator.userAgent) en lugar del ciclo lento que tiene allí.
Jeffrey Gilbert
10

La detección de funciones es mucho mejor que tratar de averiguar en qué dispositivo se encuentra y es muy difícil mantenerse al día con los nuevos dispositivos que salen todo el tiempo, una biblioteca como Modernizr le permite saber si una función en particular está disponible o no.

zadubz
fuente
18
Respondió otra pregunta que no fue la que se le preguntó. En lugar de "¿cómo puedo detectar dispositivos móviles?", Ha respondido "¿cómo puedo detectar ciertas funciones?". No toda la detección de dispositivos es para detección de características. ¿Qué pasaría si buscáramos estadísticas sobre dispositivos? Entonces no, la "detección de características" no es "mucho mejor que [averiguar el dispositivo]".
Jonathan Allard
1
Esta no es la respuesta, pero merece más que solo un comentario. La pregunta es: ¿por qué quieres detectar un navegador y luego probablemente quieras saberlo solo por la (falta de) toque? El diseño web receptivo es suficiente en la mayoría de los casos, si no en todos.
twicejr
8

¿Qué tal algo como esto?

if(
    (screen.width <= 640) || 
    (window.matchMedia && 
     window.matchMedia('only screen and (max-width: 640px)').matches
    )
  ){
   // Do the mobile thing
}
estujo
fuente
¿Por qué no solo usar screen.widthen su lugar? Me parece que es más confiable que window.matchMedia.
John Slegers
Buen punto John, no puedo recordar exactamente lo que estaba pensando en ese momento, parece poco probable (mirándolo ahora) que la segunda cláusula devuelva verdadero si la primera es falsa. Sin embargo, debe haber alguna razón por la que lo agregué.
estujo
La mayoría de los programadores decentes se sienten avergonzados cuando ven el código que escribieron un año antes. Aquellos que no solo no han crecido como programadores ;-)
John Slegers
44
La resolución de ventanas no tiene nada que ver con si un navegador está en un dispositivo móvil o no. Por ejemplo, muchos navegadores de escritorio se ejecutan en ventanas que no son de pantalla completa. Si presenta una interfaz de usuario diseñada para pantallas de mano a esos navegadores, sus usuarios tendrán una experiencia frustrante.
ɈsәɹoɈ
1
@JohnSlegers: me da vergüenza buscar en Google una pregunta y encontrar mi propia respuesta en stackoverflow. una y otra vez. Yo mismo estoy en un desbordamiento de pila constante
vsync
7

Una vez que el elemento gana el foco, lo desenfocas inmediatamente. Bootstrap-datepicker, que es un componente muy popular y bien mantenido con casi 10,000 estrellas en GitHub, utiliza este enfoque:

if (window.navigator.maxTouchPoints || 'ontouchstart' in document) {
    this.input.blur();
}

https://github.com/uxsolutions/bootstrap-datepicker

Gracias a Tigger por su ayuda.

JT Taylor
fuente
7

Una forma realmente buena de detectar dispositivos móviles o tabletas es mirar si el navegador puede crear un evento táctil.

Código JavaScript simple:

function isMobile() {
   try{ document.createEvent("TouchEvent"); return true; }
   catch(e){ return false; }
}

if (isMobile()) {
   # do whatever you wanna do!
}

Esto me funcionó muy bien, pero puede haber un problema con los dispositivos portátiles que incluyen una pantalla táctil.

No estoy seguro de si un portátil con pantalla táctil se detectará como dispositivo móvil porque aún no lo he probado.

Neo Morina
fuente
55
Las computadoras portátiles con pantalla táctil se detectarán como dispositivo móvil. Así como monitores táctiles para computadoras de escritorio. Lo creas o no, también tendrás problemas si estás usando un dispositivo de pantalla táctil para RDP en otro dispositivo que no tiene pantalla táctil.
blissfool
@blissfool, supongo que esta no será la forma correcta de detectar dispositivos móviles.
Neo Morina
Lamentablemente no. Pero, aún podría ser una opción viable para un caso de uso muy limitado.
blissfool
nunca escriba código, que se basa en una excepción, que será arrojado con seguridad en cualquier caso ...
Pablo
@Sivic solo se lanza cuando un TouchEvent no existe y el código anterior lo atrapa y devuelve falso. Este no es el caso en dispositivos móviles o tabletas u otros dispositivos con pantalla táctil.
Neo Morina
5

Aquí está mi solución rediseñada para el problema. Aún no es perfecto. La única solución verdadera sería si los fabricantes de dispositivos comienzan a tomar en serio las cadenas de agente de usuario "Móvil" y "Tableta".

window.onload = userAgentDetect;
function userAgentDetect() {
  if(window.navigator.userAgent.match(/Mobile/i)
  || window.navigator.userAgent.match(/iPhone/i)
  || window.navigator.userAgent.match(/iPod/i)
  || window.navigator.userAgent.match(/IEMobile/i)
  || window.navigator.userAgent.match(/Windows Phone/i)
  || window.navigator.userAgent.match(/Android/i)
  || window.navigator.userAgent.match(/BlackBerry/i)
  || window.navigator.userAgent.match(/webOS/i)) {
    document.body.className += ' mobile';
    alert('True - Mobile - ' + navigator.userAgent);
  } else {
    alert('False - Mobile - ' + navigator.userAgent);
  }
  if(window.navigator.userAgent.match(/Tablet/i)
  || window.navigator.userAgent.match(/iPad/i)
  || window.navigator.userAgent.match(/Nexus 7/i)
  || window.navigator.userAgent.match(/Nexus 10/i)
  || window.navigator.userAgent.match(/KFAPWI/i)) {
    document.body.className -= ' mobile';
    document.body.className += ' tablet';
    alert('True - Tablet - ' + navigator.userAgent);
  } else {
    alert('False - Tablet - ' + navigator.userAgent);
  }
}

¿Qué sucede cuando la tableta Nexus 7 solo tiene la cadena UA de Android? Primero, el dispositivo móvil se vuelve verdadero, que más tarde la tableta también se hace realidad, pero la tableta eliminará la cadena UA móvil de la etiqueta del cuerpo.

CSS:

body.tablet { background-color: green; }
body.mobile { background-color: red; }

alertLíneas agregadas para el desarrollo. La consola de Chrome puede emular muchos dispositivos de mano. Prueba allí.

EDITAR:

Simplemente no use esto, use la detección de características en su lugar. Hay tantos dispositivos y marcas por ahí que apuntar a una marca NUNCA será la solución correcta.

Lanti
fuente
4

Te aconsejo que revises http://wurfl.io/

En pocas palabras, si importa un pequeño archivo JS:

<script type='text/javascript' src="//wurfl.io/wurfl.js"></script>

te quedará un objeto JSON que se parece a:

{
 "complete_device_name":"Google Nexus 7",
 "is_mobile":true,
 "form_factor":"Tablet"
}

(eso supone que está utilizando un Nexus 7, por supuesto) y podrá hacer cosas como:

if(WURFL.form_factor == "Tablet"){
    //dostuff();
}

Esto es lo que estás buscando.

Descargo de responsabilidad: trabajo para la empresa que ofrece este servicio gratuito. Gracias.

Luca Passani
fuente
1
¿Y por qué esto no reconoce safari en iphone?
Amyth
¿Puede ampliar qué navegador está utilizando (la cadena UA exacta sería perfecta), qué datos está obteniendo y qué espera?
Luca Passani
También probé wurfl, estoy en un iPhone 5C con iOS 11.2. No reconoce Safari como un navegador móvil. Espero usar "is_mobile": true y luego "form_factor": Smartphone y tampoco volverá.
Mike Wells
Tuve que recurrir a los gurús de datos móviles de la compañía y me dicen que OS 11.2 no se ejecuta en el 5C. El dispositivo más bajo es el 5S. Entonces algo no está bien en lo que escribiste. No dude en ponerse en contacto con ScientiaMobile sin conexión para verificar dónde podría estar la desconexión. Gracias
Luca Passani
4

aquí hay un trazador de líneas

function isMobile() {
  return (typeof window.orientation !== "undefined") || (navigator.userAgent.indexOf('IEMobile') !== -1);
};
Rick Enciso
fuente
3

Depende del caso de uso. Todos los dispositivos móviles requieren una batería. Si lo que buscas es calcular la potencia sin agotar la batería, utiliza la API de estado de la batería :

navigator.getBattery().then(battery => {
  battery.charging ? 'charging' : 'not charging';
});

Si lo que está buscando es un uso de presentación matchMedia, que devuelve un valor booleano:

if (window.matchMedia("(min-width: 400px)").matches) {
  /* the viewport is at least 400 pixels wide */
} else {
  /* the viewport is less than 400 pixels wide */
}

O combínelos para una experiencia de usuario aún mejor en tabletas.

Josh Habdas
fuente
Tenga en cuenta que la API de estado de la batería se está eliminando de los navegadores.
Sora2455
La API de estado de la batería se eliminó de Firefox, pero sigue siendo una recomendación de candidato del W3C desde julio de 2016 , continúa funcionando en navegadores populares y es útil para dar forma a la experiencia.
Josh Habdas
2

Aquí hay una solución ECMAScript 6 (compatible con TypeScript)

public isMobile(): boolean {
  let check = false;
  ((a => {
      if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true;
      }))(navigator.userAgent || navigator.vendor);
  return check;
 }
0x1ad2
fuente
¿Por qué no simplemente devolver la ifcondición en lugar de tener toda esta checkvariable?
Vic
2

Hay un simple truco para detectar si es un dispositivo móvil o no. Simplemente verifique si existe el evento ontouchstart :

function isMobile()
{
    return "ontouchstart" in window;
}
Martin Wantke
fuente
3
No funcionará con computadoras portátiles y dekstop con monitores con pantalla táctil. También será un problema con las PC híbridas como Surface. Menos problema con las computadoras de escritorio, pero actualmente se venden más computadoras portátiles con pantalla táctil.
blissfool
2

Me he enfrentado a algunos escenarios donde las respuestas anteriores no funcionan para mí. Entonces se me ocurrió esto. Puede ser útil para alguien.

if(/iPhone|iPad|iPod|Android|webOS|BlackBerry|Windows Phone/i.test(navigator.userAgent)
 || screen.availWidth < 480){
//code for mobile
}

Depende de su caso de uso. Si se enfoca en el uso de la pantalla screen.availWidth, o puede usarlo document.body.clientWidthsi desea renderizar en función del documento.

Thyagarajan C
fuente
1

Lo mejor debe ser:

var isMobile = (/Mobile/i.test(navigator.userAgent));

Pero como dice Yoav Barnea ...

// Seem legit
var isMobile = ('DeviceOrientationEvent' in window || 'orientation' in window);
// But with my Chrome on windows, DeviceOrientationEvent == fct()
if (/Windows NT|Macintosh|Mac OS X|Linux/i.test(navigator.userAgent)) isMobile = false;
// My android have "linux" too
if (/Mobile/i.test(navigator.userAgent)) isMobile = true;

Después de estas 3 pruebas, espero que var isMobile sea ... ok

molokoloco
fuente
> Firefox mobile en Android no parece tener "'orientación' en la ventana"
molokoloco
1
Lo siento ... ok para mí funciona bien así ahora. "if (Modernizr.touch) / * ... * /" y continúa ...
molokoloco
Solo me pregunto cómo funcionaría Modernizr.touch cuando esté en un dispositivo de escritorio con pantalla táctil.
B2K
Para hacerlo más elegante, debe hacer todo el código te en un solo bloque if-else if-else if.
Heitor
1

Aquí está la función completa

function isMobile(){
    return (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino|android|ipad|playbook|silk/i.test(navigator.userAgent||navigator.vendor||window.opera)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test((navigator.userAgent||navigator.vendor||window.opera).substr(0,4)))
}

jQuery.noConflict();
jQuery(document).ready(function(){
    if(isMobile()) alert("Mobile"); else alert("Not Mobile");
});
David Latty
fuente
.substr (0,4) devuelve las primeras 4 letras. ¿Cómo detecta "android. + Mobile"?
Raacer
1
@raacer en realidad hay dos expresiones regulares en la respuesta (ambas en la misma línea): la primera verifica la cadena UA completa y busca Android, dispositivos móviles, etc., mientras que la segunda solo verifica los primeros 4 caracteres de la UA .
JackW
1
//true / false
function isMobile()
{
   return (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ); 
}

También puedes seguir este tutorial para detectar un móvil específico. Haga clic aquí .

gtzinos
fuente
Agregue Mobilea su RX
oriadam
1

¿Qué pasa con el uso de "window.screen.width"?

if (window.screen.width < 800) {
// do something
}

o

if($(window).width() < 800) {
//do something
}

¡Supongo que esta es la mejor manera porque hay un nuevo dispositivo móvil todos los días!

(aunque creo que no es tan compatible con los navegadores antiguos, pero pruébelo :))

Ahmad Yousef
fuente
1
¿Qué pasa con el paisaje?
Erick Voodoo
1
Esto no es muy útil para ciertos escenarios. Si se
cambia
¡Una PC es esencialmente diferente de los dispositivos móviles en usabilidad, respuesta horrible!
Heitor
1

Tenga en cuenta que la mayoría de los dispositivos móviles de nueva generación ahora tienen resoluciones superiores a 600x400. es decir, un iPhone 6 ...

Prueba de prueba: ejecutó las publicaciones más votadas y más recientes aquí, con una verificación opcional una vez que se ejecutó así:

(function(a){
    window.isMobile = (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))
})(navigator.userAgent||navigator.vendor||window.opera);

alert("This browser was found to be a % browser.", window.isMobile ? 'mobile' : 'desktop');

De alguna manera, los siguientes resultados fueron devueltos en las siguientes aplicaciones de navegador. Especificaciones: iPhone 6S, iOS 10.3.1.

Safari (último): lo detectó como un móvil.

Chrome (último): no lo detectó como un dispositivo móvil.

Entonces, probé la sugerencia de Lanti ( https://stackoverflow.com/a/31864119/7183483 ), y arrojó los resultados adecuados (móvil para todos los dispositivos iOS y escritorio para mi Mac). Por lo tanto, procedí a editarlo un poco ya que se dispararía dos veces (tanto para móviles como para tabletas). Luego me di cuenta al probar en un iPad, que también regresó como un móvil, lo que tiene sentido, desde los parámetros que Lantiutiliza comprobar el sistema operativo más que nada. Por lo tanto, simplemente moví la declaración IF de la tableta dentro del cheque móvil, lo que devolvería el móvil es que el cheque de la tableta fue negativo y la tableta de lo contrario. Luego agregué la cláusula else para que el cheque móvil regrese como computadora de escritorio / portátil, ya que ambos califican, pero luego noté que el navegador detecta la marca de CPU y sistema operativo. Así que agregué lo que se devuelve allí como parte de la instrucción if if en su lugar. Para colmo, agregué una declaración de advertencia en caso de que no se detectara nada. Vea a continuación, se actualizará con una prueba en una PC con Windows 10 pronto.

Ah, y también agregué una variable 'debugMode', para cambiar fácilmente entre depuración y compilación normal.

Descargo de responsabilidad: crédito total a Lanti , también que esto no se probó en tabletas de Windows ... que podría devolver una computadora de escritorio / portátil, ya que el sistema operativo es puro Windows. Verificará una vez que encuentre un amigo que use uno.

function userAgentDetect() {
    let debugMode = true;
    if(window.navigator.userAgent.match(/Mobile/i)
        || window.navigator.userAgent.match(/iPhone/i)
        || window.navigator.userAgent.match(/iPod/i)
        || window.navigator.userAgent.match(/IEMobile/i)
        || window.navigator.userAgent.match(/Windows Phone/i)
        || window.navigator.userAgent.match(/Android/i)
        || window.navigator.userAgent.match(/BlackBerry/i)
        || window.navigator.userAgent.match(/webOS/i)) {
        if (window.navigator.userAgent.match(/Tablet/i)
            || window.navigator.userAgent.match(/iPad/i)
            || window.navigator.userAgent.match(/Nexus 7/i)
            || window.navigator.userAgent.match(/Nexus 10/i)
            || window.navigator.userAgent.match(/KFAPWI/i)) {
            window.deviceTypeVar = 'tablet';
            if (debugMode === true) {
                alert('Device is a tablet - ' + navigator.userAgent);
            }
        } else {
            if (debugMode === true) {
                alert('Device is a smartphone - ' + navigator.userAgent);
            };
            window.deviceTypeVar = 'smartphone';
        }
    } else if (window.navigator.userAgent.match(/Intel Mac/i)) {
        if (debugMode === true) {
            alert('Device is a desktop or laptop- ' + navigator.userAgent);
        }
        window.deviceTypeVar = 'desktop_or_laptop';
    } else if (window.navigator.userAgent.match(/Nexus 7/i)
        || window.navigator.userAgent.match(/Nexus 10/i)
        || window.navigator.userAgent.match(/KFAPWI/i)) {
        window.deviceTypeVar = 'tablet';
        if (debugMode === true) {
            alert('Device is a tablet - ' + navigator.userAgent);
        }
    } else {
        if (debugMode === true) {
            alert('Device is unknown- ' + navigator.userAgent);
        }
        window.deviceTypeVar = 'Unknown';
    }
}
jlmurph
fuente
1

Este es solo un puerto es6 de la respuesta aceptada que estoy usando en mi proyecto. Tenga en cuenta que esto también incluye tabletas.

export const isMobile = () => {
  const vendor = navigator.userAgent || navigator.vendor || window.opera;

  return !!(
    /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(
      vendor
    ) ||
    /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk\/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i.test(
      vendor.substr(0, 4)
    )
  );
};
Y yo
fuente
1

return 'ontouchstart' in window && window.screen.availWidth < 768

Qué tal esto, se expande en la respuesta anterior pero también verifica el tamaño de la pantalla

Dave Keane
fuente
1

Usando Regex (de detectmobilebrowsers.com ):

/* eslint-disable */
export const IS_MOBILE = (function (a) {
  return (
    /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i
      .test(
        a.substr(0,4)
      )
  )
  // @ts-ignore
})(navigator.userAgent || navigator.vendor || window.opera)
/* eslint-enable */
Илья Зеленько
fuente
0

Esto también podría ser una solución.

var isMobile = false; //initiate as false

  // device detection
  if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) 
  || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,4))) isMobile = true;

  console.log('Mobile device:'+isMobile);

  var doc_h = $(document).height(); // returns height of HTML document
  var doc_w = $(document).width(); // returns width of HTML document
  console.log('Height: '+doc_h);
  console.log('width: '+doc_w);

  var iPadVertical = window.matchMedia("(width: 768px) and (height: 1024px) and (orientation: portrait)");
  var iPadHoricontal = window.matchMedia("(width: 1024px) and (height: 767px) and (orientation: landscape)");

  console.log('Height: '+doc_h);
  console.log('width: '+doc_w);

  if (iPadVertical.matches) {
      console.log('Ipad vertical detected');
  }else if (iPadHoricontal.matches){
      console.log('Ipad horicontal detected');
  }else {
      console.log('No Ipad');
  }

Si usa ambos métodos, obtendrá una manera perfecta de detectar diferentes dispositivos.

Viernes1978
fuente