Wykrywanie przeglądarki mobilnej

888

Szukam funkcji, która zwraca wartość logiczną, jeśli użytkownik ma przeglądarkę mobilną, czy nie.

Wiem, że mogę używać navigator.userAgenti pisać tę funkcję za pomocą wyrażenia regularnego, ale programy klienckie są zbyt różne dla różnych platform. Wątpię, aby dopasowanie wszystkich możliwych urządzeń było łatwe i myślę, że ten problem został rozwiązany wiele razy, więc powinno być jakieś kompletne rozwiązanie dla takiego zadania.

Patrzyłem na tę stronę , ale niestety skrypt jest tak tajemniczy, że nie mam pojęcia, jak użyć go do moich celów, czyli do utworzenia funkcji zwracającej wartość prawda / fałsz.

zdrowaśka
źródło
6
Powiązane: stackoverflow.com/questions/3514784/... .
Frédéric Hamidi
2
Spróbuj to przeczytać. stackoverflow.com/questions/743129/…
KyelJmD
5
@Thrustmaster: Naprawdę nie. Udostępnianie różnych JS w różnych przeglądarkach oznacza, że ​​musisz dodać Vary: User-Agentdo swojej odpowiedzi, w przeciwnym razie buforujące serwery proxy przechowają jedną wersję i wysyłają ją do innego rodzaju przeglądarki. Ale Vary: User-Agentsprawia, że ​​odpowiedź jest nieosiągalna w IE.
Bobin
16
@ave: Co próbujesz zrobić, wykrywając przeglądarkę „mobilną”? To rozróżnienie jest wysoce uzasadnione w dzisiejszym świecie tabletów i hybrydowych urządzeń komputerowych. Czy chcesz w tym przypadku wykryć małe ekrany i przedstawić inny interfejs użytkownika? Czy chcesz wykryć łączność o niskiej przepustowości? Czy chcesz wykryć interfejsy dotykowe?
Bobin
2
Zaktualizowałem więc swoją odpowiedź, aby korzystać z metody javascript wykrywacza mobilnego.com , ale zwracam wartość logiczną, jeśli ktoś nadal tego potrzebuje. ( w razie czego ). Happy Detecting :)
Michael Zaporozhets

Odpowiedzi:

1316

Za pomocą Regex (z wykryciamobilebrowsers.com ):

Oto funkcja, która używa niezwykle długiego i kompleksowego wyrażenia regularnego, który zwraca wartość a truelub w falsezależności od tego, czy użytkownik przegląda telefon komórkowy.

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

Dla tych, którzy chcą włączyć tablety do tego testu (choć prawdopodobnie nie powinieneś), możesz skorzystać z następującej funkcji:

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

Oryginalna odpowiedź

Możesz to zrobić, po prostu przeglądając listę urządzeń i sprawdzając, czy useragentpasuje coś takiego:

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

Ponieważ jednak uważasz, że ta metoda jest zawodna, możesz założyć, że każde urządzenie o rozdzielczości 800 x 600 lub mniejszej było również urządzeniem mobilnym, co jeszcze bardziej zawęziło cel (chociaż obecnie wiele urządzeń mobilnych ma znacznie wyższe rozdzielczości niż to)

to znaczy

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

Odniesienie:

Michael Zaporozhets
źródło
25
Cześć. Właśnie odwiedziłem link detmobilebrowsers.com na iPadzie 3, iOS 6.1.2 i napisano: „Nie wykryto przeglądarki mobilnej”.
Richard Lovejoy
49
@RichardLovejoy podczas tworzenia witryn, iPad zwykle nie jest uważany za telefon komórkowy.
Michael Zaporozhets
42
Ze strony about : Tablety z Androidem, iPady, Kindle Fires i PlayBooks nie są wykrywane z założenia. Aby dodać obsługę tabletów, dodaj |android|ipad|playbook|silkdo pierwszego wyrażenia regularnego.
Gras Double
13
Google TV to także system Android. Co definiuje telefon komórkowy? Rozmiar ekranu ? Dotknij? DeviceOrientation? Kiedy projektuję, chodzi bardziej o najechanie myszką czy nie, duży przycisk lub małe linki. Więc na razie uruchamiam z „if (Modernizr.touch)” :)
molokoloco
30
Cholera, cała ta idea aplikacji klienckich jest okropna i naprawdę musi się skończyć. Naprawdę musimy przestać pozwalać klientom walczyć z prądem i po prostu trzymać się zapytań medialnych. Jeśli chcą dokonywać przekierowań na podstawie skali dla poszczególnych stron, wystarczy sprawdzić zakres konkretnego zapytania medialnego za pośrednictwem JS, tj. Tylergaw.com/articles/reacting-to-media-queries-in-javascript
marksyzm
324

Co powiesz na:

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

... ponieważ smartfony zwykle obsługują tę właściwość, a przeglądarki stacjonarne nie.

EDYCJA: Jak wskazał @Gajus, to rozwiązanie jest obecnie przestarzałe i nie powinno być używane ( https://developer.mozilla.org/en-US/docs/Web/API/Window/orientation )

Yoav Barnea
źródło
14
to jest naprawdę wyjątkowe i niesamowite, nie masz nic przeciwko, jeśli dodam to do mojej odpowiedzi?
Michael Zaporozhets
77
To prawdopodobnie nie zadziała długo. 1) Tablety mogą mieć przyzwoite rozmiary ekranu, chcesz, aby wyświetlały pełną stronę internetową na komputery stacjonarne, ale będą miały tę właściwość 2) Windows 8 jest tutaj, a wraz z nim kilka laptopów z ekranem dotykowym i obracającymi się ekranami.
Dave Hilditch
10
co do twojego pierwszego punktu na temat tabletów o przyzwoitych rozmiarach ekranu - myślę, że możesz przedstawić te same argumenty dla wszystkich innych rozwiązań (tablet z dużym ekranem, który jest śledzony jako mały ekran). w każdym razie chodzi tutaj o poszukiwanie własności, która jest współdzielona przez małe urządzenia zamiast utrzymywania długiego kodu obsługi i dodawania wyrażenia regularnego z każdym nowym urządzeniem / wersją / modelem. Myślę, że wykrywanie urządzeń należy już do przeszłości i dziś musimy skupić się na wykrywaniu funkcji. jeszcze raz będę zadowolony z bardziej odpowiedniej nieruchomości w tej sprawie ...
yoav barnea
2
Uwielbiam to i działa idealnie, dziękuję. Dla mojego rozwiązania byłem po prostu prosty.
Bojangles,
40
window.orientationto przestarzała właściwość ( developer.mozilla.org/en-US/docs/Web/API/Window/orientation , zgodność.spec.whatwg.org /# dom-window-orientation ), którą niektóre przeglądarki mobilne wybierają do obsługi z nieznanych przyczyn . Implementacja tych samych przeglądarek window.screen.orientation(która jest również zdefiniowana w przeglądarkach komputerowych). Mogę tylko założyć, że window.orientationzostało tam ze względów starszych i dlatego nie powinien być stosowany w nowych aplikacjach.
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());
    }
};

Jak używać

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

Aby sprawdzić, czy użytkownik korzysta z określonego urządzenia mobilnego:

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

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

Ulepszona wersja na github: https://github.com/smali-kazmi/detect-mobile-browser

Mudaser Ali
źródło
Dlaczego nie zrobić any()for ... w pętli isMobileczłonków ORed ?
SomeShinyObject
@ChristopherW utworzyłem wtyczkę i zmodyfikowałem kod zgodnie z zaleceniami
Mudaser Ali
2
Może przesunąć system iOS przed BlackBerry () tylko po to, by na pierwszym miejscu postawić bardziej popularne przypadki i pozwolić wczesnemu ratunkowi zaoszczędzić trochę dodatkowego przetwarzania?
Rob_vH
2
@Rob_vH Umieściłem ten kod w github ( github.com/smali-kazmi/detect-mobile-browser ) z kilkoma zaawansowanymi funkcjami; możesz również wysyłać tam sugestie
Mudaser Ali
1
@AkarshSatija Czy spadek wydajności po tych 5 testach regularnych faktycznie wpływa na którąkolwiek z twoich aplikacji? Byłbym bardzo zaskoczony, gdyby tak się stało. Przedwczesna optymalizacja może być stratą czasu ...
trusktr
68

Oto proste rozwiązanie ze źródła procy Facebooka

var isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
if (isMobile) {
  /* your code here */
}
Santhosh
źródło
Miły. Bardzo przydatny w niektórych sytuacjach
Chuck Le Butt
Przydatne w przypadku wykrycia urządzenia, na którym można zainstalować aplikację mobilną. Przecież nie zależy ci na przeglądarce. Tylko urządzenie / system operacyjny.
Charlie Reitzel,
30

Przybyłem tutaj, szukając prostego, czystego sposobu na wykrycie „urządzeń z ekranem dotykowym”, które klasyfikuję jako telefony komórkowe i tablety. W obecnych odpowiedziach nie znalazłem czystego wyboru, ale opracowałem następujące, które mogą również komuś pomóc.

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

Edycja : Aby jednocześnie obsługiwać komputery stacjonarne z ekranem dotykowym i telefony komórkowe, możesz użyć:

var touchDevice = (navigator.maxTouchPoints || 'ontouchstart' in document.documentElement);
Tygrys
źródło
9
Co się stanie, jeśli monitor na pulpicie obsługuje dotyk?
Anton Kuzmin
@HappyCoder Uważam, że to do systemu operacyjnego należy informowanie przeglądarki, kiedy ekran dotykowy na pulpicie jest aktywny. Tak, tak, ta kontrola powinna być nadal ważna.
Tigger
(+1) jednak mój pulpit, którego używam, ma teraz ekran dotykowy i nie zawsze jest spójny touchstart|end|etc.
Cody,
1
Datepicker bootstrap wykorzystuje następujące elementy: if (window.navigator.msMaxTouchPoints || 'ontouchstart' w dokumencie) {this.input.blur (); }
JT Taylor
1
@JTTaylor Wygląda na to, że Microsoft zaleca navigator.maxTouchPoints (bez msprefiksu). Jest też artykuł MDN do sprawdzenia.
Tigger
20

Jak wielu stwierdziło, poleganie na ruchomym celu danych klienta użytkownika jest problematyczne. To samo można powiedzieć o liczeniu na ekranie.

Moje podejście zapożyczono z techniki CSS, aby ustalić, czy interfejs jest dotykowy:

Używając tylko javascript (obsługa wszystkich współczesnych przeglądarek), dopasowanie zapytania medialnego może łatwo wywnioskować, czy urządzenie jest mobilne .

function isMobile() {
    var match = window.matchMedia || window.msMatchMedia;
    if(match) {
        var mq = match("(pointer:coarse)");
        return mq.matches;
    }
    return false;
}
gsxrboy73
źródło
6
Co z laptopami z wyświetlaczami z obsługą dotykową?
Maxim
6
Sprawdziłbym! MatchMedia („(dowolny wskaźnik: w porządku)”). Pasuje do siebie. („Nie podłączono myszy”, zamiast „ma ekran dotykowy”.
Sora2455 30.01.19
Działa to, podczas gdy mój ostatni skrypt zostałby oszukany przez osoby korzystające z funkcji powiększania w przeglądarce (np. Facet, z którym rozmawiałem na 13-calowym ekranie z 4K, który spadł do 1080p i nadal musiał korzystać z powiększenia). Pracowałem na moim iPhonie (Safari / urządzenia Firefox) i Android (Waterfox / Chrome / "Przeglądarka") zdecydowanie. dużo bardziej niezawodny niż wszystkie wyżej-głosowało odpowiedzi.
John
nie wykrywa fenka FireFox na Androidzie, dla którego uzupełniałem navigator.userAgent.toLowerCase (). indexOf ('fennec')> -1 (być może nie najlepszy dodatek ..)
StayCool
2
Dodatkowo możesz przetestować właściwość hover: dla smartfonów i ekranów dotykowych @media (hover: brak) i (wskaźnik: gruby)
Batailley
16

Zgodnie z artykułem MDN na temat wykrywania przeglądarki przy użyciu klienta , zaleca się unikanie tego podejścia, jeśli to możliwe, i sugerowanie innych sposobów, takich jak wykrywanie funkcji.

Jeśli jednak trzeba użyć klienta użytkownika jako środka do wykrywania, czy urządzenie jest mobilne, sugerują:

Podsumowując, zalecamy wyszukanie ciągu „Mobi” w dowolnym miejscu w User Agent, aby wykryć urządzenie mobilne.

Dlatego wystarczy jedna linijka:

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

[AKTUALIZACJA]:

Jak sugeruje @ zenw0lf w komentarzach, lepiej byłoby użyć wyrażenia regularnego:

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

TheDarkIn1978
źródło
.includesnie wspierane przez IE-11
Pasha Oleynik
1
@PashaOleynik polifill może to naprawić
Maxim
Tablet Nexus 7 z Androidem nie ma Mobileciągu agenta użytkownika
Alex Sorokoletov
@AlexSorokoletov Również dla artykułu 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
Myślę, że to zadziałałoby w dowolnym miejscu bez wypełniaczy: const isMobile = /Mobi/.test(window.navigator.userAgent)
zenw0lf
14

Nie ma idealnego rozwiązania do wykrywania, czy kod JS jest wykonywany w przeglądarce mobilnej, ale następujące dwie opcje powinny w większości przypadków działać.

Opcja 1: wąchanie przeglądarki

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

Ten konkretny kod podsłuchujący przeglądarkę jest biblioteką o nazwie isMobile .


Opcja 2: orientacja okna

Sprawdź, czy window.orientationjest zdefiniowany:

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


Uwaga

Nie wszystkie urządzenia z ekranem dotykowym są mobilne i odwrotnie. Tak więc, jeśli chcesz zaimplementować coś specjalnie dla ekranu dotykowego, nie powinieneś testować, czy twoja przeglądarka działa na urządzeniu mobilnym, a raczej czy urządzenia obsługują ekran dotykowy:

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

John Slegers
źródło
Orientacja jest naprawdę fajna! ))
Maxim,
1
Podoba mi się twoje window.orientationrozwiązanie, ale doktorzy mówią, że jest przestarzałe! developer.mozilla.org/en-US/docs/Web/API/Window/orientation
skwidbreth 10.04.2018
3
Podejście do orientacji NIE jest przyjemne, ponieważ system Windows 8 i nowsze wersje mogą zmieniać orientację.
Heitor,
Windows 8 i nowsze wersje koncentrują się na dodaniu obsługi telefonów komórkowych, ale także hybryd (laptopów, które można konwertować na duże pady), dlatego orientacja zawodzi jako metoda wykrywania, nawet jeśli moz nie określał go jako przestarzały.
Jeff Clayton
Pochodzi z Win 7 z zainstalowanym oprogramowaniem graficznym, może zmienić orientację, ale zadaj sobie pytanie, kto może na komputerze stacjonarnym / laptopie użyć innej orientacji ekranu, takiej jak Portret zamiast Krajobrazu i używać i przez jeszcze ponad 1 minutę. Nikt !!! Zmiana orientacji na pulpicie oznacza, że ​​zaczniesz czytać znaki na ekranie od dołu do góry.
GirlCode
11

Oto rozwiązanie UserAgent, które jest bardziej skuteczne niż dopasowanie ...

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
źródło
7
w metodzie testowej nie jest rozróżniana wielkość liter, ale wyrażenie regularne jest. możesz po prostu oflagować wyrażenie regularne bez rozróżniania wielkości liter z „i” na końcu i zrób/iphone|etc/i.test(navigator.userAgent)
xec
11

Aby dodać dodatkową warstwę kontroli, używam pamięci HTML5, aby wykryć, czy używa ona pamięci mobilnej czy stacjonarnej. Jeśli przeglądarka nie obsługuje pamięci, mam tablicę mobilnych nazw przeglądarek i porównuję agenta użytkownika z przeglądarkami w tablicy.

To jest dość proste. Oto funkcja:

// 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
źródło
3
Nie testowałem jeszcze na urządzeniach mobilnych, ale sessionStorage.desktopnie istnieje w przeglądarce Safari, Chrome ani Firefox (wszystkie najnowsze wersje w momencie publikacji). Otrzymujesz jednak głos w górę, ponieważ twoje rozwiązanie idzie w lepszym kierunku niż inne. Ale nie zapomnij użyć var mobile =zamiast mobile =.
shuckster
3
Również dobrym pomysłem jest nie używanie indexOf w starszych przeglądarkach, które nie obsługują tej metody, lub używanie polifillu. Nie jest konieczne używanie toLowerCase na liście małych liter, ani nie jest to konieczne, jeśli używasz /ipad|iphone|etc/i.test(navigator.userAgent) zamiast wolnej pętli, którą tam masz.
Jeffrey Gilbert
10

Wykrywanie funkcji jest znacznie lepsze niż próba ustalenia, na którym urządzeniu się znajdujesz, i bardzo trudno jest nadążyć za nowymi urządzeniami, biblioteka taka jak Modernizr informuje, czy dana funkcja jest dostępna, czy nie.

zadubz
źródło
18
Odpowiedziałeś na inne pytanie niż zadane. Zamiast „jak mogę wykryć urządzenie mobilne?”, Odpowiedziałeś „jak mogę wykryć niektóre funkcje?”. Nie każde wykrywanie urządzenia służy do wykrywania funkcji. Co jeśli chcielibyśmy uzyskać statystyki dotyczące urządzeń? Zatem nie, „wykrywanie funkcji” nie jest „dużo lepsze niż [wykrycie urządzenia]”.
Jonathan Allard
1
To nie jest odpowiedź, ale zasługuje na coś więcej niż tylko komentarz. Pytanie brzmi: dlaczego chcesz wykryć przeglądarkę, a potem prawdopodobnie będziesz chciał ją poznać tylko z powodu (braku) dotyku. Responsywne projektowanie stron internetowych wystarcza w większości, jeśli nie we wszystkich przypadkach.
twicejr
8

Co powiesz na coś takiego?

if(
    (screen.width <= 640) || 
    (window.matchMedia && 
     window.matchMedia('only screen and (max-width: 640px)').matches
    )
  ){
   // Do the mobile thing
}
stujo
źródło
Dlaczego nie użyć screen.widthzamiast tego? Wydaje mi się, że jest bardziej niezawodny niż window.matchMedia.
John Slegers,
Dobra uwaga, John, nie mogę sobie przypomnieć dokładnie tego, co wtedy myślałem, wydaje się mało prawdopodobne (patrząc na to teraz), że druga klauzula zwróci prawdę, jeśli pierwsza będzie fałszywa. Musiałem jednak mieć jakiś powód, dla którego to dodałem.
stujo
Większość porządnych programistów wstydzi się, gdy widzi kod napisany przez siebie rok wcześniej. Ci, którzy nie dorastali już jako programiści ;-)
John Slegers
4
Rozdzielczość okna nie ma nic wspólnego z tym, czy przeglądarka jest na urządzeniu mobilnym, czy nie. Na przykład wiele przeglądarek stacjonarnych działa w oknach nie pełnoekranowych. Jeśli w tych przeglądarkach zaprezentujesz interfejs użytkownika przeznaczony do ekranów podręcznych, ich użytkownicy będą mieli frustrujące doświadczenia.
ʇsәɹoɈ
1
@JohnSlegers - Wstydzę się Googling pytania i znajdowania własnej odpowiedzi na stackoverflow. znowu i znowu. Ja sam jestem w ciągłym przepełnieniu stosu
vsync
7

Gdy element zyska ostrość, natychmiast go rozmyjesz. Bootstrap-datepicker, który jest bardzo popularnym i dobrze utrzymanym składnikiem z prawie 10.000 gwiazd w GitHub, wykorzystuje to podejście:

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

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

Dzięki Tigger za pomoc.

JT Taylor
źródło
7

Naprawdę dobrym sposobem na wykrycie urządzeń mobilnych lub tabletów jest sprawdzenie, czy przeglądarka może utworzyć zdarzenie dotykowe.

Zwykły kod JavaScript:

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

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

To działało dla mnie naprawdę dobrze, ale może występować problem z urządzeniami laptopów, które zawierają ekran dotykowy.

Nie jestem pewien, czy laptop z ekranem dotykowym zostanie wykryty jako urządzenie mobilne, ponieważ jeszcze go nie testowałem.

Neo Morina
źródło
5
Laptopy z ekranem dotykowym zostaną wykryte jako urządzenia mobilne. Jak również monitory z ekranem dotykowym do komputerów stacjonarnych. Wierzcie lub nie, ale będziecie mieć problem, jeśli używasz urządzenia z ekranem dotykowym do RDP na innym urządzeniu, które nie ma ekranu dotykowego.
blissfool
@blissfool Chyba nie będzie to właściwy sposób na wykrycie urządzeń mobilnych.
Neo Morina,
Niestety nie. Ale nadal może być opłacalną opcją w przypadku bardzo ograniczonego zastosowania.
blissfool
nigdy nie pisz kodu opartego na wyjątku, który na pewno zostanie rzucony w każdym razie ...
Pablo
@Sivic jest rzucany tylko wtedy, gdy nie istnieje TouchEvent, a powyższy kod łapie go i zwraca false. Nie dotyczy to urządzeń mobilnych, tabletów i innych urządzeń z ekranem dotykowym.
Neo Morina,
5

Oto moje przemyślane rozwiązanie problemu. Wciąż nie jest idealny. Jedynym prawdziwym rozwiązaniem byłoby, gdyby producenci urządzeń zaczęli poważnie traktować ciągi agenta użytkownika „Mobile” i „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);
  }
}

Co się stanie, gdy tablet Nexus 7 ma tylko ciąg znaków UA? Po pierwsze, komórka staje się prawdą, później tablet staje się również prawdą, ale tablet usunie ciąg Mobile UA z tagu body.

CSS:

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

alertlinie dodane do programowania. Konsola Chrome może emulować wiele urządzeń przenośnych. Przetestuj tam.

EDYTOWAĆ:

Po prostu nie używaj tego, zamiast tego użyj funkcji wykrywania. Istnieje tak wiele urządzeń i marek, że kierowanie na markę NIGDY nie będzie właściwym rozwiązaniem.

Lanti
źródło
4

Radzę sprawdzić http://wurfl.io/

Krótko mówiąc, jeśli importujesz mały plik JS:

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

pozostanie obiekt JSON, który wygląda następująco:

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

(przy założeniu, że używasz Nexusa 7, oczywiście) i będziesz mógł robić takie rzeczy jak:

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

Tego właśnie szukasz.

Oświadczenie: Pracuję dla firmy, która oferuje tę bezpłatną usługę. Dzięki.

Luca Passani
źródło
1
I dlaczego to nie rozpoznaje safari na iPhonie?
Amyth,
Czy możesz rozwinąć przeglądarkę, z której korzystasz (dokładny ciąg UA byłby idealny), jakie dane otrzymujesz i czego oczekujesz?
Luca Passani,
Ja też próbowałem wurfl, jestem na iPhonie 5C z systemem IOS 11.2. Safari nie rozpoznaje przeglądarki Safari jako przeglądarki mobilnej. Spodziewam się użyć „is_mobile”: true, a następnie „form_factor”: smartfon i też nie wraca.
Mike Wells,
Musiałem zwrócić się do guru Mobile Data w firmie, a oni powiedzieli mi, że OS 11.2 nie działa na 5C. Najniższym urządzeniem jest 5S. Więc coś jest nie tak z tym, co napisałeś. Skontaktuj się z ScientiaMobile offline, aby sprawdzić, gdzie może być rozłączenie. Dzięki
Luca Passani,
4

Oto jedna linijka

function isMobile() {
  return (typeof window.orientation !== "undefined") || (navigator.userAgent.indexOf('IEMobile') !== -1);
};
Rick Enciso
źródło
3

Zależy od przypadku użycia. Wszystkie urządzenia mobilne wymagają baterii. Jeśli szukasz mocy obliczeniowej bez rozładowywania baterii, użyj interfejsu API stanu baterii :

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

Jeśli szukasz prezentacji matchMedia, która zwraca wartość logiczną:

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

Lub połącz je, aby uzyskać jeszcze lepszą obsługę na tabletach.

Josh Habdas
źródło
Pamiętaj, że interfejs API stanu baterii jest usuwany z przeglądarek.
Sora2455
Interfejs API stanu baterii został usunięty z przeglądarki Firefox, ale od lipca 2016 r. Pozostaje rekomendacją dla kandydatów na W3C , nadal działa w popularnych przeglądarkach i jest przydatny w tworzeniu doświadczeń.
Josh Habdas
2

Oto rozwiązanie ECMAScript 6 (kompatybilne z 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
źródło
dlaczego nie po prostu zwrócić ifwarunek zamiast mieć tę całą checkzmienną?
Vic
2

Prostą sztuczką jest wykrycie, czy jest to urządzenie mobilne, czy nie. Wystarczy sprawdzić, czy istnieje zdarzenie ontouchstart :

function isMobile()
{
    return "ontouchstart" in window;
}
Martin Wantke
źródło
3
Nie działa z laptopami i dekstops z monitorami z ekranem dotykowym. Będzie również problem z komputerami hybrydowymi, takimi jak Surface. Mniej problemu z komputerami stacjonarnymi, ale w dzisiejszych czasach sprzedaje się więcej laptopów z ekranem dotykowym.
blissfool
2

Napotkałem kilka scenariuszy, w których powyższe odpowiedzi nie działają dla mnie. Więc wymyśliłem to. Może być komuś pomocny.

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

To zależy od twojego przypadku użycia. Jeśli skupiasz się na użyciu ekranu screen.availWidthlub możesz użyć, document.body.clientWidthjeśli chcesz renderować na podstawie dokumentu.

Thyagarajan C.
źródło
1

Najlepsze muszą być:

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

Ale tak jak mówi 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;

Po tych 3 testach mam nadzieję, że var isMobile jest ... ok

molokoloco
źródło
> Firefox na Androida nie wydaje się mieć „orientacji w oknie”
molokoloco
1
Przepraszam .. ok dla mnie to działa teraz tak dobrze. „if (Modernizr.touch) / * ... * /” i kontynuuj ...
molokoloco
Zastanawiam się, jak działałby Modernizr.touch na urządzeniu stacjonarnym z ekranem dotykowym.
B2K
Aby uczynić go bardziej eleganckim, powinieneś zrobić cały kod w jednym bloku if-else if-else if.
Heitor,
1

Oto pełna funkcja

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
źródło
.substr (0,4) zwraca pierwsze 4 litery. Jak wykrywa „Android. + Mobile”?
raacer
1
@raacer w rzeczywistości są dwa wyrażenia regularne w odpowiedzi (oba w tej samej linii) - pierwszy sprawdza względem całego ciągu UA i szuka Androida, telefonu komórkowego itp., podczas gdy drugi sprawdza tylko względem pierwszych 4 znaków UA .
JackW
1
//true / false
function isMobile()
{
   return (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ); 
}

możesz również wykonać ten samouczek, aby wykryć określony telefon komórkowy. Kliknij tutaj .

gtzinos
źródło
Dodaj Mobiledo swojego RX
oriadam
1

co z użyciem „window.screen.width”?

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

lub

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

To chyba najlepszy sposób, ponieważ każdego dnia pojawia się nowe urządzenie mobilne!

(chociaż myślę, że nie jest tak obsługiwane w starych przeglądarkach, ale spróbuj :))

Ahmad Yousef
źródło
1
Co jest z krajobrazem?
Erick Voodoo
1
Nie jest to bardzo przydatne w niektórych scenariuszach.
Zmiana
Komputer zasadniczo różni się od urządzeń mobilnych pod względem użyteczności, przerażająca odpowiedź !!
Heitor
1

Pamiętaj, że większość urządzeń mobilnych nowej generacji ma teraz rozdzielczości większe niż 600 x 400. tj. iPhone 6 ....

Dowód testu: uruchomiłem tutaj najbardziej uprzywilejowane i najnowsze posty, z opcjonalnym sprawdzeniem po uruchomieniu tak:

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

Jakoś następujące wyniki zostały zwrócone w następujących aplikacjach przeglądarki. Specyfikacja: iPhone 6S, iOS 10.3.1.

Safari (najnowszy): wykryto jako urządzenie mobilne.

Chrome (najnowszy): nie wykryłem go jako telefonu komórkowego.

SO, następnie przetestowałem sugestię od Lanti ( https://stackoverflow.com/a/31864119/7183483 ) i zwróciło prawidłowe wyniki (mobilne dla wszystkich urządzeń iOS i stacjonarne dla mojego Maca). Dlatego zacząłem go trochę edytować, ponieważ uruchomi się dwukrotnie (zarówno na telefonie komórkowym, jak i tablecie). Zauważyłem wtedy podczas testowania na iPadzie, że zwrócił również jako telefon komórkowy, co ma sens, ponieważ parametry, które Lantiużywa sprawdzić system operacyjny bardziej niż cokolwiek innego. Dlatego po prostu przeniosłem instrukcję IF tabletu do czeku mobilnego, który zwróciłby komórkę, jeśli wynik testu tabletu był ujemny, a tablet inaczej. Następnie dodałem klauzulę else, aby czek mobilny powrócił jako komputer stacjonarny / laptop, ponieważ oba kwalifikują się, ale zauważyłem, że przeglądarka wykrywa markę procesora i systemu operacyjnego. Więc zamiast tego dodałem to, co jest tam zwracane w ramach instrukcji else if. Podsumowując, dodałem ostrzeżenie, na wypadek gdyby nic nie zostało wykryte. Zobacz poniżej, wkrótce zaktualizuje się z testem na komputerze z systemem Windows 10.

Aha, a także dodałem zmienną „debugMode”, aby łatwo przełączać się między debugowaniem a normalną kompilacją.

Zastrzeżenie: pełne uznanie dla Lanti , a także to, że nie zostało to przetestowane na tabletach z systemem Windows ... które mogą zwrócić komputer stacjonarny / laptop, ponieważ system operacyjny to czysty Windows. Sprawdzę, gdy znajdę przyjaciela, który go używa.

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
źródło
1

To tylko port es6 zaakceptowanej odpowiedzi , której używam w swoim projekcie. Pamiętaj, że dotyczy to również tabletów.

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)
    )
  );
};
I ja
źródło
1

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

Co powiesz na to, rozszerza się przy odpowiedzi powyżej, ale sprawdza również rozmiar ekranu

Dave Keane
źródło
1

Za pomocą Regex (z wykryciamobilebrowsers.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 */
Илья Зеленько
źródło
0

To może być również rozwiązanie.

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

Jeśli użyjesz obu metod, uzyskasz doskonały sposób na wykrycie różnych urządzeń.

Friis1978
źródło