Detectando um navegador móvel

889

Estou procurando uma função que retorne valor booleano se o usuário tiver um navegador móvel ou não.

Eu sei que posso usar navigator.userAgente escrever essa função usando regex, mas os user-agents são muito variados para plataformas diferentes. Duvido que corresponder a todos os dispositivos possíveis seria fácil, e acho que esse problema já foi resolvido muitas vezes, portanto deve haver algum tipo de solução completa para essa tarefa.

Eu estava olhando para este site , mas, infelizmente, o script é tão enigmático que não tenho idéia de como usá-lo para o meu propósito, que é criar uma função que retorne verdadeiro / falso.

ave
fonte
6
Relacionado: stackoverflow.com/questions/3514784/… .
Frédéric Hamidi
2
Tente ler isso. stackoverflow.com/questions/743129/…
KyelJmD
5
@ Thrustmaster: Realmente não. Servir JS diferentes para diferentes navegadores significa que você deve adicionar Vary: User-Agentà sua resposta; caso contrário, os proxies em cache armazenarão uma versão e a enviarão para o outro tipo de navegador. Mas Vary: User-Agenttorna a resposta inacessível no IE.
99912
17
@ave: O que você está tentando fazer detectando um navegador "móvel"? A distinção é altamente discutível no mundo atual de tablets e dispositivos de computação híbridos. Você procura detectar telas pequenas e apresentar uma interface diferente nesse caso? Você está procurando detectar conectividade de baixa largura de banda? Você está procurando detectar interfaces de toque?
99912
2
Atualizei minha resposta para usar o método javascript detectmobilebrowsers.com , mas retorne um valor booleano se alguém ainda precisar disso. ( apenas no caso de ). Feliz Detectando :)
Michael Zaporozhets

Respostas:

1318

Usando o Regex (de detectmobilebrowsers.com ):

Aqui está uma função que usa um regex incrivelmente longo e abrangente que retorna um valor trueou falsedependendo de o usuário estar ou não navegando com um celular.

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 aqueles que desejam incluir tablets neste teste (embora não seja possível), você pode usar a seguinte função:

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

A resposta original

Você pode fazer isso simplesmente percorrendo uma lista de dispositivos e verificando se o useragentresultado corresponde a algo assim:

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

No entanto, como você acredita que esse método não é confiável, você pode presumir que qualquer dispositivo que tenha uma resolução de 800x600 ou menos também seja um dispositivo móvel, restringindo ainda mais o seu objetivo (embora atualmente muitos dispositivos móveis tenham resoluções muito maiores que essa)

ie

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

Referência:

Michael Zaporozhets
fonte
25
Olá, Acabei de visitar o link detectmobilebrowsers.com no meu iPad 3, iOS 6.1.2, e diz "Nenhum navegador móvel detectado".
Richard Lovejoy
49
@RichardLovejoy ao construir sites, o ipad geralmente não é considerado móvel.
Michael Zaporozhets
42
Na página about : tablets, iPads, Fires Kindle e PlayBooks Android não são detectados por design. Para adicionar suporte para tablets, adicione |android|ipad|playbook|silkao primeiro regex.
Gras Double
13
O Google TV também é Android. O que define um celular? Tamanho da tela ? Toque ? deviceOrientation? Quando eu desenho, é mais uma questão de passar o mouse ou não, botões grandes ou pequenos links. Assim, por agora, eu funciono com "if (Modernizr.touch)" :)
molokoloco
31
Gawd, toda essa idéia de agentes de usuário é horrível e realmente precisa parar. Nós realmente precisamos parar de permitir que os clientes lutem contra a maré e ficar com as consultas da mídia. Se eles querem fazer redirecionamentos com base na escala para páginas específicas, em seguida, basta verificar o intervalo de uma determinada mídia de consulta via JS ou seja tylergaw.com/articles/reacting-to-media-queries-in-javascript
marksyzm
324

E se:

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

... como os smartphones geralmente suportam essa propriedade e os navegadores de desktop não.

EDIT: Como o @Gajus apontou, esta solução agora está obsoleta e não deve ser usada ( https://developer.mozilla.org/en-US/docs/Web/API/Window/orientation )

yoav barnea
fonte
14
isso é realmente super exclusivo e incrível, você se importa se eu adicionar à minha resposta?
Michael Zaporozhets
77
Provavelmente isso não vai funcionar por muito tempo. 1) Os tablets podem ter tamanhos de tela decentes, você deseja que eles exibam o site completo da área de trabalho, mas eles terão essa propriedade 2) O Windows 8 está aqui e com ele vários laptops com tela sensível ao toque e telas que rodam.
Dave Hilditch
10
quanto ao seu primeiro argumento sobre tablets com tamanhos de tela decentes - acho que você também poderia argumentar para todas as outras soluções (um tablet com tela grande rastreada como tela pequena). de qualquer maneira, a idéia aqui é procurar propriedades que sejam compartilhadas por pequenos dispositivos, em vez de manter o código longo da manutenção e adicionar regex a cada novo dispositivo / versão / modelo que estiver por vir. Acho que a detecção de dispositivos pertence ao passado e hoje precisamos nos concentrar na detecção de recursos. Eu estarei contente de propriedade aqui sobre mais adequado para que o assunto ...
yoav barnea
2
Adoro e funciona perfeitamente, obrigado. Para minha solução, eu estava logo atrás do simples.
Bojangles
40
window.orientationé uma propriedade preterida ( developer.mozilla.org/en-US/docs/Web/API/Window/orientation , compat.spec.whatwg.org/#dom-window-orientation ) que alguns navegadores móveis optam por oferecer suporte por razões desconhecidas . Os mesmos navegadores implementam window.screen.orientation(que também é definido nos navegadores de desktop). Só posso presumir que window.orientationresta por motivos herdados e, portanto, não deve ser usado em novos aplicativos.
Gajus 8/02
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());
    }
};

Como usar

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

Para verificar se o usuário está em um dispositivo móvel específico:

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

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

Versão aprimorada no github: https://github.com/smali-kazmi/detect-mobile-browser

Mudaser Ali
fonte
Por que não fazer any()um loop for ... in de isMobilemembros do ORed ?
SomeShinyObject
@ChristopherW i tinha criado seu plugin e modificou o código como você aconselhou
Mudaser Ali
2
Talvez mova o iOS à frente do BlackBerry () apenas para colocar os casos mais comuns em primeiro lugar e permitir que o resgate antecipado economize algum processamento extra?
Rob_vH
2
@ Rob_vH eu coloquei esse código no github ( github.com/smali-kazmi/detect-mobile-browser ) com alguns recursos avançados; você está aberto para enviar sugestões lá também
Mudaser Ali 13/03
1
@AkarshSatija A queda de desempenho dessas 5 verificações de regex realmente afeta algum de seus aplicativos? Eu ficaria muito surpreso se isso acontecesse. Otimização prematura pode ser um desperdício de tempo ...
trusktr
68

Aqui está uma solução simples da fonte do estilingue do facebook

var isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
if (isMobile) {
  /* your code here */
}
Santhosh
fonte
Agradável. Muito útil em determinadas situações
Chuck Le Butt
Útil para o caso de detectar um dispositivo em que um aplicativo móvel possa ser instalado. Você não se importa com o navegador, por si só. Apenas o dispositivo / SO.
Charlie Reitzel
31

Vim aqui procurando uma maneira simples e limpa de detectar "dispositivos com telas sensíveis ao toque", que eu classifico como móveis e tablets. Não encontrou uma opção limpa nas respostas atuais, mas elaborou o seguinte, que também pode ajudar alguém.

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

Editar : para oferecer suporte a áreas de trabalho com uma tela sensível ao toque e celulares ao mesmo tempo, você pode usar o seguinte:

var touchDevice = (navigator.maxTouchPoints || 'ontouchstart' in document.documentElement);
Tigre
fonte
9
E se o monitor da área de trabalho suportar o toque?
Anton Kuzmin
@HappyCoder Acredito que cabe ao sistema operacional avisar o navegador quando a tela de toque em uma área de trabalho estiver ativa. Portanto, sim, essa verificação ainda deve ser válida.
Tigger
(+1), no entanto, minha área de trabalho que estou usando agora tem uma tela sensível ao toque e nem sempre é consistente touchstart|end|etc.
Cody
1
O datepicker do bootstrap usa o seguinte: if (window.navigator.msMaxTouchPoints || 'ontouchstart' no documento) {this.input.blur (); }
JT Taylor
1
@JTTaylor Parece que a Microsoft está recomendando navigator.maxTouchPoints (sem msprefixo). Há também um artigo MDN para verificar.
Tigger
20

Como muitos declararam, confiar no alvo móvel dos dados do agente do usuário é problemático. O mesmo pode ser dito para contar com o tamanho da tela.

Minha abordagem é emprestada de uma técnica CSS para determinar se a interface é sensível ao toque:

Usando apenas javascript (compatível com todos os navegadores modernos), uma correspondência de consulta de mídia pode inferir facilmente se o dispositivo é móvel .

function isMobile() {
    var match = window.matchMedia || window.msMatchMedia;
    if(match) {
        var mq = match("(pointer:coarse)");
        return mq.matches;
    }
    return false;
}
gsxrboy73
fonte
6
E os laptops com telas sensíveis ao toque?
Maxim
6
Eu procuraria! MatchMedia ("(any-pointer: fine)"). Corresponde a mim mesmo. ("Nenhum mouse conectado" ao invés de "possui uma tela sensível ao toque".
Sora2455 30/01/19
Isso funciona, enquanto o meu último script seria enganado por pessoas que usassem o recurso de zoom do navegador (por exemplo, um cara com quem eu estava conversando em uma tela de 13 "com 4K que caiu para 1080p e ainda precisava usar o zoom). Trabalhei no meu iPhone (Safari / Firefox) e Android dispositivos (Waterfox / Chrome / "browser") Definitivamente. muito mais confiável do que tudo o mais elevado respostas up-votado.
João
não detecta FireFox fennec em um Android para o qual eu suplementado com navigator.userAgent.toLowerCase () indexOf ( 'Fennec')> -1 (talvez não o melhor suplemento ..).
Staycool
2
Além disso, você pode testar a propriedade hover: para smartphones e telas sensíveis ao toque @media (hover: none) e (ponteiro: grosso)
Batailley
16

De acordo com o artigo da MDN sobre a detecção do navegador usando o agente do usuário , é recomendável evitar essa abordagem, se possível, e sugerir outros caminhos, como a detecção de recursos.

No entanto, se for necessário usar o agente do usuário como um meio para detectar se o dispositivo é móvel, eles sugerem:

Em resumo, recomendamos procurar a string "Mobi" em qualquer lugar do User Agent para detectar um dispositivo móvel.

Portanto, este one-liner será suficiente:

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

[ATUALIZAR]:

Como @ zenw0lf sugere nos comentários, seria melhor usar uma expressão regular:

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

TheDarkIn1978
fonte
.includesnão sopport por IE-11
Pasha Oleynik #
1
@PashaOleynik um polyfill pode consertar isso #
Maxim
O tablet Nexus 7 com Android não possui Mobilea sequência de agentes do usuário
Alex Sorokoletov 22/01
@AlexSorokoletov Também para o artigo da 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
Eu acho que isso funcionaria em qualquer lugar sem polyfills: const isMobile = /Mobi/.test(window.navigator.userAgent)
zenw0lf
14

Não existe uma solução perfeita para detectar se o código JS é executado em um navegador móvel, mas as duas opções a seguir devem funcionar na maioria dos casos.

Opção 1: cheirar o 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');

Esse código específico de detecção de navegador é o de uma biblioteca chamada isMobile .


Opção 2: window.orientation

Teste se window.orientationestá definido:

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


Nota

Nem todos os dispositivos touchscreen são móveis e vice-versa. Portanto, se você deseja implementar algo específico para a tela sensível ao toque, não deve testar se o navegador está sendo executado em um dispositivo móvel, mas se os dispositivos têm suporte para a tela sensível ao toque:

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

John Slegers
fonte
A abordagem de orientação é muito legal! ))
Maxim
1
Gosto da sua window.orientationsolução, mas os documentos dizem que está obsoleta! developer.mozilla.org/en-US/docs/Web/API/Window/orientation
skwidbreth
3
A abordagem de orientação NÃO é boa, porque o Windows 8 e superior podem alterar a orientação.
Heitor
O Windows 8 e mais recentes estão focados em adicionar suporte para celulares, mas também híbridos (laptops que podem ser convertidos em grandes pads), e é por isso que a orientação falha como um método de detecção, mesmo que o moz não esteja se referindo a ela como obsoleto.
Jeff Clayton
É do Win 7, com o software gráfico instalado, que pode mudar a orientação, mas faça uma pergunta a si mesmo: quem pode usar no Desktop / Laptop uma outra orientação na tela, como Retrato, em vez de Paisagem, e usar i por mais de um minuto. Ninguém !!! Alterar a orientação na área de trabalho significa que você começará a ler os caracteres na tela de baixo para cima.
GirlCode 17/04
11

Aqui está uma solução userAgent que é mais eficaz do que a correspondência ...

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
fonte
7
o método de teste não diferencia maiúsculas de minúsculas, mas seu regex é. você poderia simplesmente bandeira para o caso regex insensível com um "i" no final e fazer/iphone|etc/i.test(navigator.userAgent)
XEC
11

Para adicionar uma camada extra de controle, eu uso o armazenamento HTML5 para detectar se ele está usando armazenamento móvel ou de desktop. Se o navegador não suportar armazenamento, tenho uma variedade de nomes de navegadores móveis e comparo o agente do usuário com os navegadores da matriz.

É bem simples. Aqui está a função:

// 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
fonte
3
Ainda não testei no celular, mas sessionStorage.desktopnão existe no Safari, Chrome ou Firefox (todas as versões mais recentes no momento da publicação). Você recebe uma votação positiva, já que sua solução vai em uma direção melhor do que outras. Mas não se esqueça de usar em var mobile =vez de mobile =.
shuckster
3
Também é uma boa idéia não usar indexOf com navegadores mais antigos que ainda não suportam esse método ou usar um polyfill. Não é necessário usar o toLowerCase em uma lista de valores em minúsculas, nem é necessário fazê-lo se você estiver executando /ipad|iphone|etc/i.test(navigator.userAgent) em vez do loop lento que você tem por lá.
Jeffrey Gilbert
10

A detecção de recursos é muito melhor do que tentar descobrir em qual dispositivo você está e muito difícil acompanhar os novos dispositivos que saem o tempo todo. Uma biblioteca como o Modernizr permite que você saiba se um recurso específico está disponível ou não.

zadubz
fonte
18
Você respondeu a outra pergunta que não foi solicitada. Em vez de "como posso detectar dispositivos móveis?", Você respondeu "como posso detectar determinados recursos?". Nem toda detecção de dispositivo é para detecção de recursos. E se estivéssemos procurando obter estatísticas sobre dispositivos? Então não, a "detecção de recursos" não é "muito melhor do que [descobrir o dispositivo]".
Jonathan Allard 01/01
1
Esta não é a resposta, mas merece mais do que apenas um comentário. A questão é: por que você deseja detectar um navegador e provavelmente desejará conhecê-lo apenas por causa da (falta de) toque. Web design responsivo é suficiente na maioria, se não em todos os casos.
twicejr
8

Que tal algo como isso?

if(
    (screen.width <= 640) || 
    (window.matchMedia && 
     window.matchMedia('only screen and (max-width: 640px)').matches
    )
  ){
   // Do the mobile thing
}
stujo
fonte
Por que não usar apenas screen.width? Parece-me que é mais confiável do que window.matchMedia.
John Slegers 12/03
Bom argumento, John, não me lembro exatamente o que estava pensando na época, parece improvável (olhando agora) que a segunda cláusula retorne verdadeira se a primeira for falsa. Deve ter havido algum motivo pelo qual eu o adicionei.
stujo
Muitos programadores decentes sentem vergonha ao ver o código que escreveram um ano antes. Aqueles que não só não têm crescido como programadores ;-)
John Slegers
4
A resolução da janela não tem nada a ver com o navegador estar em um dispositivo móvel ou não. Por exemplo, muitos navegadores de desktop são executados em janelas que não são de tela cheia. Se você apresentar uma interface do usuário projetada para telas portáteis a esses navegadores, os usuários terão uma experiência frustrante.
precisa saber é o seguinte
1
@ JohnSlegers - Estou com muita vergonha pesquisando uma pergunta no Google e encontrando minha própria resposta no stackoverflow. de novo e de novo. Eu mesmo estou em um constante estouro de pilha
vsync 03/04
7

Quando o elemento ganha foco, você o desfoca imediatamente. O bootstrap-datepicker, que é um componente muito popular e bem mantido, com quase 10.000 estrelas no GitHub, usa esta abordagem:

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

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

Obrigado ao Tigger pela assistência.

JT Taylor
fonte
7

Uma maneira realmente boa de detectar dispositivos móveis ou tablets é verificar se o navegador pode criar um evento de toque.

Código JavaScript simples:

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

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

Isso funcionou muito bem para mim, mas pode haver um problema com os laptops, que incluem uma tela sensível ao toque.

Não tenho certeza se um laptop com tela sensível ao toque será detectado como um dispositivo móvel porque ainda não o testei.

Neo Morina
fonte
5
Os laptops com tela sensível ao toque serão detectados como dispositivo móvel. Bem como monitores de tela de toque para desktops. Acredite ou não, você também terá problemas se estiver usando o dispositivo de tela sensível ao toque para fazer RDP em outro dispositivo que não tenha uma tela de toque.
blissfool
@blissfool Eu acho que esse não será o caminho certo para detectar dispositivos móveis.
Neo Morina
Infelizmente não. Mas, ainda pode ser uma opção viável para um caso de uso muito limitado.
blissfool
Nunca escrever código, que é baseado em uma exceção, que será throwen com certeza, em qualquer caso ...
Pablo
@Sivic só é lançado quando um TouchEvent não existe e o código acima o pega e retorna false. Este não é o caso em dispositivos móveis, tablets ou outros dispositivos com tela de toque.
Neo Morina
5

Aqui está a minha solução repensada para o problema. Ainda não é perfeito. A única solução verdadeira seria se os fabricantes de dispositivos começarem a levar a sério as seqüências de agente do usuário "Mobile" e "Tablet".

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

O que acontece quando o tablet Nexus 7 tem apenas a string do Android UA? Primeiro, o Mobile se tornará verdadeiro; mais tarde, o Tablet também se tornará verdadeiro, mas o Tablet excluirá a string do Mobile UA da etiqueta do corpo.

CSS:

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

alertlinhas adicionadas para desenvolvimento. O console do Chrome pode emular muitos dispositivos portáteis. Teste lá.

EDITAR:

Só não use isso, use a detecção de recursos. Existem tantos dispositivos e marcas por aí que segmentar uma marca NUNCA será a solução certa.

Lanti
fonte
4

Aconselho que você verifique http://wurfl.io/

Em poucas palavras, se você importar um pequeno arquivo JS:

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

você ficará com um objeto JSON que se parece com:

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

(supondo que você esteja usando um Nexus 7, é claro) e poderá fazer coisas como:

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

Isto é o que você está procurando.

Isenção de responsabilidade: trabalho para a empresa que oferece este serviço gratuito. Obrigado.

Luca Passani
fonte
1
E como isso não reconhece o safari no iphone?
Amyth 6/09/16
Você pode expandir o navegador que está usando (a string exata do UA seria perfeita), quais dados você está obtendo e o que espera?
Luca Passani
Eu também tentei wurfl, estou em um iPhone 5C executando o IOS 11.2. Não está reconhecendo o Safari como um navegador móvel. Estou esperando usar "is_mobile": true e depois "form_factor": Smartphone e também não está retornando.
Mike Wells
Eu tive que recorrer aos gurus do Mobile Data na empresa e eles me disseram que o OS 11.2 não roda no 5C. O dispositivo mais baixo é o 5S. Então, algo não está certo no que você escreveu. Sinta-se à vontade para entrar em contato com o ScientiaMobile offline para verificar onde pode estar a desconexão. Obrigado
Luca Passani
4

aqui está um forro

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

Depende do caso de uso. Todos os dispositivos móveis requerem uma bateria. Se você procura computação sem energia, use a API de status da bateria :

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

Se o que você está procurando é uso de apresentação matchMedia, que retorna um 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 */
}

Ou combine-os para uma experiência de usuário ainda melhor em tablets.

Josh Habdas
fonte
Observe que a API de status da bateria está sendo removida dos navegadores.
precisa saber é o seguinte
A API de status da bateria foi removida do Firefox, mas permanece uma recomendação de candidato do W3C desde julho de 2016 , continua a funcionar em navegadores populares e é útil na modelagem da experiência.
Josh Habdas 30/01/19
2

Aqui está uma solução ECMAScript 6 (pronta para 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
fonte
por que não apenas retornar a ifcondição em vez de ter toda essa checkvariável?
Vic
2

Há um truque simples para detectar se é um dispositivo móvel ou não. Basta verificar se o evento ontouchstart existe:

function isMobile()
{
    return "ontouchstart" in window;
}
Martin Wantke
fonte
3
Não funciona com laptops e dekstops com monitores touchscreen. Também haverá um problema com PCs híbridos como o Surface. Menos problema com os desktops, mas há mais laptops com tela de toque sendo vendidos atualmente.
precisa saber é o seguinte
2

Já enfrentei alguns cenários em que as respostas acima não funcionam para mim. Então eu vim com isso. Pode ser útil para alguém.

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

Depende do seu caso de uso. Se você se concentrar no uso da tela screen.availWidthou document.body.clientWidthse desejar renderizar com base no documento.

Thyagarajan C
fonte
1

O melhor deve ser:

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

Mas como Yoav Barnea diz ...

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

Após esses 3 testes, espero que o var isMobile seja ... ok

molokoloco
fonte
O Firefox mobile no Android parece não ter "'orientação' na janela"
molokoloco 30/05
1
Desculpe .. ok para mim, funciona bem assim agora. "if (Modernizr.touch) / * ... * /" e continue ...
molokoloco
Apenas imaginando como o Modernizr.touch funcionaria quando estivesse em um dispositivo de desktop com tela de toque.
B2K
Para torná-lo mais elegante, você deve criar todo o código te em apenas um bloco se-se-se-se.
Heitor
1

Aqui está ele função 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
fonte
.substr (0,4) retorna as primeiras 4 letras. Como ele detecta "android. + Mobile"?
raacer
1
@raacer Na verdade, existem duas expressões regulares na resposta (ambas na mesma linha) - a primeira verifica contra toda a cadeia de caracteres da UA e procura android, dispositivos móveis etc., enquanto a segunda verifica apenas os 4 primeiros caracteres da UA .
JackW
1
//true / false
function isMobile()
{
   return (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ); 
}

Além disso, você pode seguir este tutorial para detectar um celular específico. Clique aqui .

gtzinos
fonte
Por favor, adicione Mobileao seu RX
oriadam 11/07
1

que tal usar "window.screen.width"?

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

ou

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

Eu acho que essa é a melhor maneira, porque há um novo dispositivo móvel todos os dias!

(embora eu ache que não é compatível com navegadores antigos, mas tente :))

Ahmad Yousef
fonte
1
O que é a paisagem?
Erick Voodoo
1
Isso não é muito útil para certos cenários. Se o navegador de desktop é redimensionado ele talvez detectado incorretamente como um navegador móvel
toing_toing
Um PC é essencialmente diferente de dispositivos móveis em usabilidade, resposta horrível !!
Heitor
1

Observe que a maioria dos dispositivos móveis de nova geração agora possui resoluções maiores que 600x400. ou seja, um iPhone 6 ....

Prova de teste: executou as postagens mais votadas e mais recentes aqui, com uma verificação opcional uma vez executada da seguinte forma:

(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 alguma forma, os seguintes resultados foram retornados nos seguintes aplicativos do navegador. Especificações: iPhone 6S, iOS 10.3.1.

Safari (mais recente): detectado como móvel.

Chrome (mais recente): não o detectou como um celular.

Então, testei a sugestão do Lanti ( https://stackoverflow.com/a/31864119/7183483 ) e ele retornou os resultados adequados (móvel para todos os dispositivos iOS e desktop para meu Mac). Portanto, procedi a editá-lo um pouco, pois seria acionado duas vezes (para dispositivos móveis e tablets). Notei, ao testar em um iPad, que ele também retornava como um celular, o que faz sentido, pois os Parâmetros que Lantiusa verificar o sistema operacional mais do que qualquer coisa. Portanto, eu simplesmente movi a instrução IF do tablet para dentro da verificação móvel, que retornaria para celular, caso a verificação do Tablet fosse negativa e o tablet, caso contrário. Em seguida, adicionei a cláusula else para que a verificação móvel retorne como desktop / laptop, pois os dois se qualificam, mas notei que o navegador detecta as marcas de CPU e SO. Então, eu adicionei o que é retornado lá como parte da instrução if if. Para resumir, eu adicionei uma declaração preventiva no caso de nada ser detectado. Veja abaixo, será atualizado com um teste em um PC com Windows 10 em breve.

Ah, e eu também adicionei uma variável 'debugMode', para alternar facilmente entre a depuração e a compilação normal.

Dislaimer: Crédito total para Lanti , também porque isso não foi testado em Windows Tablets ... o que pode retornar um desktop / laptop, pois o sistema operacional é puro Windows. Verificarei quando encontrar um amigo que use um.

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
fonte
1

Esta é apenas uma porta es6 da resposta aceita que estou usando no meu projeto. Observe que isso também inclui tablets.

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)
    )
  );
};
E eu
fonte
1

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

Que tal isso, ele se expande na resposta acima, mas também verifica o tamanho da tela

Dave Keane
fonte
1

Usando o 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 */
Илья Зеленько
fonte
0

Isso também pode ser uma solução.

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

Se você usar os dois métodos, obterá uma maneira perfeita de detectar dispositivos diferentes.

Friis1978
fonte