1779

Is there a way to detect whether or not a user is using a mobile device in jQuery? Something similar to the CSS @media attribute? I would like to run a different script if the browser is on a handheld device.

The jQuery $.browser function is not what I am looking for.

Jonathan S.
  • 400
  • 1
  • 13
superUntitled
  • 21,375
  • 26
  • 81
  • 106
  • 8
    Provide a mobile URL specifically for mobile devices. This is how most major sites handle mobile devices. See http://m.google.com. – meager Aug 18 '10 at 17:27
  • 6
    jQuery does not, and cannot do everything. It is provides cross-browser DOM traversal and manipulation, simple animation and ajax between browsers, and creates a skeleton framework for plugins to build upon. Please be aware of jQuery's limitations before asking *specifically* for a jQuery solution. – Yi Jiang Aug 22 '10 at 05:38
  • 1
    I just noticed that Modernizr supports "CSS3 like" Media Queries: http://www.modernizr.com/docs/#mq – Bart Aug 10 '11 at 21:32
  • 85
    User agents are constantly moving targets, everyone reading this post should be very wary of user agent sniffing – Rob Jan 09 '12 at 10:38
  • 53
    What's a 'mobile' device? Is it a device that supports touch (including Chrome Pixels and Windows 8 laptops with mice)? Is it a device with a small screen (what about retina iPads)? Is it a device with a slow CPU? Or a device with a slow internet connection? Depending on what you want to do the answer to this question will vary. To target screen resolution or touch is easy. If you want to serve up smaller content or less intensive JS for some devices, then there's no silver bullet. Test for window.navigator.connection and fall back to (nasty, bad, ill-advised) userAgent sniffing. My 2 cents. – David Gilbertson Jul 09 '13 at 04:42
  • @DavidGilbertson Why would a slow internet connection make it a mobile device? For all you know, I could be using a satellite internet connection (ex: Google Loon) for my home network. – Cole Johnson Aug 19 '13 at 02:24
  • 4
    @Cole"Cole9"Johnson My point exactly. 'Mobile' seems to be used as an umbrella term for touch, slow CPU, slow network and small screen. But none of these are perfect assumptions. I believe that considering these individually will result in a better product than designing for some vague concept of 'mobile'. Hence me posing that question to the OP. – David Gilbertson Aug 20 '13 at 02:38
  • @DavidGilbertson for me, "mobile" encompasses phones, iPods, and anything that really fits in your pocket. A NetBook (if you remember what those are) isn't "mobile" because you can't fit it in your pocket. It's _portable_, but it's not mobile. – Cole Johnson Aug 20 '13 at 03:15
  • 1
    @DavidGilbertson I would classify a mobile device as something that isn't meant to function as a fully-featured PC (i.e. Windows, OSX, or countless Linux distros). I know that the line gets rather blurry with Ubuntu Mobile and Linux dual-boots on Android devices, but the distinction is usually most easily made by the OS running on the device (Android isn't a fully featured desktop OS, while Windows 8 is generally not the mobile-oriented one). – Isiah Meadows Jan 19 '14 at 01:54
  • I think that [Interaction Media Features](https://www.w3.org/TR/mediaqueries-4/#mf-interaction) are the solution here. (See [my answer](http://stackoverflow.com/a/42835826/703717) to this [similar question](http://stackoverflow.com/questions/12469875/how-to-code-css-media-queries-targeting-all-mobile-devices-and-tablets/42835826#42835826)) – Danield Mar 16 '17 at 14:07
  • Related: [What's the best way to detect a 'touch screen' device using JavaScript?](https://stackoverflow.com/q/4817029/55075) – kenorb Jul 17 '17 at 15:43
  • use cdn `https://cdnjs.cloudflare.com/ajax/libs/jquery-browser/0.1.0/jquery.browser.js` then in your code where you want to check for mobile just use `$.browser.mobile` it will return true if current device is a mobile. To check for desktop use `$.browser.desktop` – Laksh Goel Jan 19 '18 at 07:18
  • Instead of trying to detect a "mobile device", I would try and detect a small screen size. After all, you want to optimize for screen size, right? – Elijah Mock Dec 05 '19 at 00:02
  • Let me guess, the problem is not really to detect if user is on mobile or not, but to layout elements on the page? I guess width/height will give the most reliable solutions. – Bitterblue Jan 06 '20 at 13:52
  • 1
    I have scrolled down on all answers and none of them seems to be good. How is this possible? still no solution ? – Dimitri Kopriwa Apr 28 '20 at 10:33
  • @DimitriKopriwa **TL;DR: `let isMobile = /mobi/i.test(navigator.userAgent);`** – Andrew Feb 22 '21 at 21:23

59 Answers59

2147

Editor's note: user agent detection is not a recommended technique for modern web apps. See the comments below this answer for confirmation of this fact. It is suggested to use one of the other answers using feature detection and/or media queries.


Instead of using jQuery you can use simple JavaScript to detect it:

if( /Android|webOS|iPhone|iPad|Mac|Macintosh|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
 // some code..
}

Or you can combine them both to make it more accessible through jQuery...

$.browser.device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));

Now $.browser will return "device" for all above devices

Note: $.browser removed on jQuery v1.9.1. But you can use this by using jQuery migration plugin Code


A more thorough version:

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;
}
sweets-BlingBling
  • 4,432
  • 2
  • 14
  • 14
  • 1
    ipad would be navigator.userAgent.match(/iPad/i) ? – Panthro Sep 12 '11 at 16:07
  • Yes. The (String).match regular expression test checks for the presence of "iPad" in the user agent string. – sweets-BlingBling Sep 16 '11 at 10:38
  • Try navigator.userAgent.match(/BlackBerry/), – sweets-BlingBling Nov 16 '11 at 06:50
  • 476
    User agent sniffing is a very noddy detection technique, user agent strings are a constant moving target, they should not be trusted alone. People up-voting this post should consider researching more. – Rob Jan 09 '12 at 10:42
  • 72
    One of the problems with sniffing for just specific devices out of the user agent is that you have to remember to update your detection when new devices come out. This isn't an ideal solution. – ICodeForCoffee Nov 28 '12 at 17:26
  • 4
    User agent sniffing is not reliable and ever changing, this is not a good approach at all. http://webaim.org/blog/user-agent-string-history/ – Brandon Buck Jan 10 '13 at 21:12
  • 2
    Hate to be an echo but the point can be emphasised enough. DON'T use user-agent detection. – the_new_mr Jan 14 '13 at 10:44
  • 12
    The Dolphin browser on android does not send any of those strings! – feeela Jan 24 '13 at 14:31
  • 2
    my answer over on [this answer](http://stackoverflow.com/a/11381730/1061967) seems to offer the same deal but be a hell of a lot more comprehensive ( just a heads up ), with detection method credit going to http://detectmobilebrowsers.com/ – Michael Zaporozhets Feb 15 '13 at 12:55
  • 92
    If your user is crafty enough or the developers dumb enough to change the user agent string, who cares about them... – mattdlockyer Mar 22 '13 at 17:02
  • 2
    I agree Matt. If your application has very sensitive/important mission critical features, you're better off using a different approach, which will probably involve having an entirely separate mobile site/application. I'd argue that this is approach is probably acceptable for most cases. We're not in the mid 90's anymore guys... – Throttlehead Mar 22 '13 at 21:22
  • 2
    Agree with the "Don't do user agent sniffing" its not reliable, the better way to go is Feature detection like Modernizr http://modernizr.com/ – zadubz Apr 05 '13 at 00:16
  • 4
    sniffing may be bad, but there is a number of scenarios where it is the only way to go. Like showing a pop-up window to Android and iOs users to install a mobile app while ignoring other less-popular mobile OSes. –  May 15 '13 at 04:24
  • 1
    var mobile = ('DeviceOrientationEvent' in window || 'orientation' in window); /* My Chrome desktop on window have DeviceOrientationEvent == fct() */ if (/Windows NT|Macintosh/i.test(navigator.userAgent)) mobile = false; – molokoloco May 30 '13 at 12:35
  • @sweets-BlingBling your native js detection is amazing but, is it possible to separate mobile and tablet devices on this equation? – Barlas Apaydin Jul 01 '13 at 15:06
  • 62
    So how mobile would you consider an android TV with mouse? How mobile is a windows PC that can run in dual mode (with keyboard, or as touch screen)? If you did this before the iPad was invented, then you had to add it later to all your sites. Next OSs coming out: Ubuntu Mobile, FirefoxOS, Tizen... `.This.Is.A.Bad.Idea.` – FrancescoMM Jul 04 '13 at 09:58
  • 4
    There are so many possible user agent strings missing from there. HP slate (`HP Slate 7|HP ElitePad 900|hp-tablet|EliteBook.*Touch`), Microsoft Surface (`Windows NT [0-9.]+; ARM;`), PSVita (`Playstation.*(Portable|Vita)`) ar ejust the ones off the top of my head. There are literally thousands of manufacturer-specific ones which don't include `Android` or similar in the string. Consider using a library that compiles these into an efficient test for you and just keep the library up to date. – Mike Dec 09 '13 at 14:37
  • this does not work for Z10. what match do i use for Z10 – Neville Nazerane Feb 03 '14 at 04:58
  • 6
    With the flag 'i' (ignore case) you do not need to use the toLowerCase() function. – Dg Jacquard Feb 20 '14 at 19:06
  • 'applewebkit' is also a Chrome userAgent on the Desktop. – Dg Jacquard Feb 20 '14 at 20:19
  • A lot of the mobiles would be missed from here http://www.useragentstring.com/pages/Mobile%20Browserlist/ – giorgio79 Feb 22 '14 at 13:14
  • Modified [@Andy Ray's](http://stackoverflow.com/questions/3514784/what-is-the-best-way-to-detect-a-handheld-device-in-jquery?page=1&tab=oldest#comment14034239_3540295) version: `(/iPhone|iPod|iPad|Android|BlackBerry|BB10|RIM Tablet|Windows Phone|SymbianOS|Kindle|Silk/).test(navigator.userAgent)`. Some Black Berry, WP, Symbian, Amazon, Playstation devices have been added to regex. – Alex Vauch Sep 12 '14 at 13:15
  • add `Kindle|Silk|KFTT|KFOT|KFJWA|KFJWI|KFSOWI|KFTHWA|KFTHWI|KFAPWA|KFAPWI` to that – SpYk3HH Mar 27 '15 at 17:40
  • 1
    This works for jQuery (as constrained by the question itself,) but I think it should be said that it's probably not a good idea to test against user against. @BriceFavre has also mentioned this. Something like modernizr is probably a better solution. – Bobby Russell Nov 11 '15 at 22:41
  • 1
    @Bobby Russell But what does modernizer do under the table? – Mateus Viccari Jun 07 '16 at 12:06
  • I created a Jquery plugin for only this purpose: https://github.com/nixarsoft/mobilebrowser/blob/master/jquery.mobilebrowser.js You can use this like this: if( $.isMobile() ) { alert("mobile"); } else { alert("not mobile"); } – kodmanyagha Jan 28 '17 at 18:28
  • A better approach is to follow Mozilla´s recommendation on detecting a mobile device: https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent. See the following answer below: http://stackoverflow.com/a/24600597/1829959 – RNobel Feb 07 '17 at 11:28
  • @Rob are you aware of any better alternatives?? – oldboy May 16 '17 at 22:10
  • 2
    @Anthony CSS media queries, feature detection, … – phk May 18 '17 at 13:01
  • @phk CSS3 since the resolution of some cellphones nowadays is better than some old laptops and desktop monitors, just how reliable are css3 media queries? or am i missing something? – oldboy May 18 '17 at 18:48
  • 1
    @Anthony `device-pixel-ratio`, `orientation`, matching DPI (https://hacks.mozilla.org/2013/09/css-length-explained/) – phk May 18 '17 at 18:53
  • 1
    @Anthony yes, feature detection as many others including phk have suggested. You can enhance a users experience by checking the feature you want is available in their browser. – Rob May 25 '17 at 09:10
  • Good lord man, at least offer a warning along with your answer. It can way wrong in a hurry. – Telarian Feb 06 '19 at 21:36
  • 1
    Hmm, this breaks on iOS 13.2, where mobile safari's userAgent is "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Safari/605.1.15". – Bill Keese Nov 11 '19 at 21:10
  • IMHO it would be nice to put some code on start of a page to check does visitor device has touchscreen ability; if does, then it's mobile device. – Isma Dec 13 '20 at 21:36
  • 1
    Also, why is Mac in there? That is included even on MacOS – kyleplo Feb 21 '21 at 19:58
595

For me small is beautiful so I'm using this technique:

In CSS file:

/* Smartphones ----------- */
@media only screen and (max-width: 760px) {
  #some-element { display: none; }
}

In jQuery/JavaScript file:

$( document ).ready(function() {      
    var is_mobile = false;

    if( $('#some-element').css('display')=='none') {
        is_mobile = true;       
    }

    // now I can use is_mobile to run javascript conditionally

    if (is_mobile == true) {
        //Conditional script here
    }
 });

My objective was to have my site "mobile-friendly". So I use CSS Media Queries do show/hide elements depending on the screen size.

For example, in my mobile version I don't want to activate the Facebook Like Box, because it loads all those profile images and stuff. And that's not good for mobile visitors. So, besides hiding the container element, I also do this inside the jQuery code block (above):

if(!is_mobile) {
    (function(d, s, id) {
        var js, fjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) return;
        js = d.createElement(s); js.id = id;
        js.src = "//connect.facebook.net/pt_PT/all.js#xfbml=1&appId=210731252294735";
        fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));
}

You can see it in action at http://lisboaautentica.com

I'm still working on the the mobile version, so it's still not looking as it should, as of writing this.

Update by dekin88

There is a JavaScript API built-in for detecting media. Rather than using the above solution simply use the following:

$(function() {      
    let isMobile = window.matchMedia("only screen and (max-width: 760px)").matches;

    if (isMobile) {
        //Conditional script here
    }
 });

Browser Supports: http://caniuse.com/#feat=matchmedia

The advantage of this method is that it's not only simpler and shorter, but you can conditionally target different devices such as smartphones and tablets separately if necessary without having to add any dummy elements into the DOM.

Gonçalo Peres
  • 895
  • 1
  • 6
  • 3
  • Yes this is what I was thinking of as well, and it is great solution. Unfortunately I am working now on project where I need to know exactly what device OS it is and have to use more JS for that... thumbs up for good solution though – Tomas Jul 31 '12 at 09:27
  • 9
    Don't you need #some-element ACTUALLY IN THE DOM for this to work? – Rimer Sep 21 '12 at 02:26
  • Yes Rimer.
    needs to exist in the DOM.
    – Gonçalo Peres Oct 03 '12 at 14:37
  • 71
    -1 The [`screen.width` property](https://developer.mozilla.org/en-US/docs/DOM/window.screen.width) is a global. There's no need to arbitrarily add an element to the DOM and unnecessarily bring in CSS media queries. Plus, if the browser is on a desktop and the user resizes the window, `$is_mobile` is not going to be updated. – merv Nov 09 '12 at 15:46
  • I like it... The jQuery should be fired on resize too `$(window).resize(function(){ ... });` and the condition I would write `if($('#some-element').is(':hidden')){ ... }`. Perfect. – Thomas Jan 08 '13 at 17:33
  • 110
    Why not: `if( screen.width <= 480 ) { // is mobile }` – andrewrjones Jan 20 '13 at 01:05
  • 1
    You could use JavaScript to add the (empty) element to the end of the body, just before testing. Then you wouldn't have to worry about whether every document has it in the HTML. On the other hand, it would be even easier to just test `if ($(window).width() <= 760)` – Blazemonger Jun 14 '13 at 17:10
  • 23
    @andrewrjones Retina devices double the `width` attribute value IIRC. Therefore, a retina iPhone will have a `width` of `640` and a height of `960` in portrait, and a `width` of `960` and a height of `640` in landscape. – Cole Johnson Aug 19 '13 at 02:18
  • 1
    Media queries using `*-width` are the same as testing `document.documentElement.clientWidth` in JavaScript. `*-device-width` would be `screen.width` – Alex W Aug 19 '13 at 19:18
  • 76
    You've just reinvented `window.matchMedia`: https://developer.mozilla.org/en-US/docs/Web/API/Window.matchMedia – Paul Irish Feb 26 '14 at 19:27
  • 5
    -1 There's a lot of mobile devices already that are full hd(1920x1080) – Diego Plentz Mar 04 '14 at 17:50
  • This doesn't seem to work with BlackBerry because it doesn't support media queries – Fabio Napodano Apr 21 '14 at 10:40
  • 2
    I like this (orginal, pre-edit) solution, "asking" an (possibly creating it temporarily) element of a css property to know whether my layout is in "mobile mode", because I avoid redundantly writing and maintaining media-queries between css and javascript. – Torin Finnemann Apr 28 '14 at 10:48
  • Sorry this solution does not work, even adding a listener. Android Galaxy Ace. So better not to use it. – peterincumbria May 11 '14 at 08:11
  • in the CSS media query `max-width: 760px` -> Why use the number `760`? – AGamePlayer Jun 29 '14 at 04:31
  • 2
    @PaulIrish `window.matchMedia` is not working in IE < 10 and IE Mobile – mykola.rykov Jul 24 '14 at 17:46
  • There are FullHD phones and your code is just useless. Resolution is not the most important thing to keep in mind for phones. Lets say jQuery datePicker doesnt work on phones even if res is ok. – Tommix Oct 28 '14 at 13:41
  • I can just minimize my desktop browser to that size, does that mean it is mobile? No! – SearchForKnowledge Dec 04 '14 at 14:17
  • For me, this has been a very difficult battle. The determination between phone, tablet, and desktop. Because the viewport width on a desktop can be changed to be the width of a mobile device, and back to full size. One problem with @andrewrjones solution of using `if( screen.width <= 480 ) { // is mobile }` is that the specified pixel value in a CSS media query does not match the value returned from `screen.width`. This is because `screen.width` does not include the scrollbar width, but the CSS media query does. I strongly dislike UA sniffing, but it's provided a reliable solution thus far. – kyle.stearns Jan 06 '15 at 17:37
  • @andrewrjones (and *merv*) if you are already using css to control which width should be used for be considered "mobile" **then** there's no reason to add another redundant parameter in javascript. design decision should go on css so I think this is a better approach. – cregox May 04 '15 at 19:55
  • @PaulIrish: window.matchMedia is not reliable AFAIK. It's still a working draft and would not work in legacy browsers. I wouldn't rely on that. – Ruchira Apr 06 '16 at 04:35
  • 1
    Lovely with the solution using `window.matchMedia()` - that's my accepted answer <3 – Nam G VU Aug 17 '16 at 07:48
  • Not good, for example i need to avoid some video to load if i'm on a mobile device. Simply hide the element won't solve the problem, will load but not how. – Marcelo Rocha Oct 18 '16 at 22:45
  • Nice solution, I wanted to mention one addition to using `window.matchMedia`. It does return an object, so if you're looking for a boolean to use the `matches` field works great! – Ryan Boken Jul 13 '17 at 15:43
  • Your solution seems elegant, but I would not call the loading of all that jQuery library as something **small** and **beautiful**. – statosdotcom Mar 18 '18 at 04:53
  • puts the last answer first please? I read everything and arrived at the end almost jumped for joy xD – KevynTD Feb 18 '19 at 07:42
  • 2
    If you are going to use `matchMedia` you really should check for `max-device-width` and **not** `max-width`. Orientation comes into play as well (width becoming height in landscape) so a better solutions would be: `window.matchMedia(\`(max-device-${window.matchMedia('(orientation: portrait)').matches?'width':'height'}: ${411}px)\`).matches` (where 411 is a somewhat arbitrary upper limit for a phone). MatchMedia is a good start for checking handheld but I'd always combine with a check for touch events (which is async so a good reason to save in localStorage). – Sjeiti Mar 22 '19 at 10:29
  • I'd prefer this way since a RWD designed page almost have some element need to be hide/show in mobile browser mode. – RRTW Apr 29 '19 at 02:24
  • 1
    This answer totally misses the point of the question. The OP asked how to detect a mobile device, not how to detect a small screen. Today's mobile devices have ridiculous screen resolutions and this approach is really wrong and misleading. In some cases, we need to detect a mobile device to disable "on hover" functionalities, which don't exist on mobile devices. – Mladen B. May 15 '19 at 07:08
  • I love this approach so much, thank you for the reply man, wish you the best !! – que1326 Nov 06 '19 at 13:06
  • 3
    I like this approach, I lifted `window.matchMedia("(pointer:coarse)").matches;` from a different answer. – Jason Lydon Feb 13 '20 at 16:44
  • @JasonLydon, thanks a million for that comment! It's the best solution by far! – Ivan Mar 29 '20 at 11:25
  • See https://stackoverflow.com/questions/54763579/distinguish-between-touch-only-and-mouse-and-touch-devices for an incredibly simple answer to this. – Mmm Jul 29 '20 at 22:42
  • 1
    Some devices when in the landscape can surpass your dimensions, therefore, missing to detect some landscaped oriented devices – Karue Benson Karue Aug 10 '20 at 23:16
266

According to Mozilla - Browser detection using the user agent:

In summary, we recommend looking for the string “Mobi” anywhere in the User Agent to detect a mobile device.

Like this:

if (/Mobi/.test(navigator.userAgent)) {
    // mobile!
}

This will match all common mobile browser user agents, including mobile Mozilla, Safari, IE, Opera, Chrome, etc.

Update for Android

EricL recommends testing for Android as a user agent also, as the Chrome user agent string for tablets does not include "Mobi" (the phone versions do however):

if (/Mobi|Android/i.test(navigator.userAgent)) {
    // mobile!
}
Daniel Hanrahan
  • 4,222
  • 6
  • 26
  • 42
  • 11
    Thanks for the answer! I prefer `/Mobi/i.test(navigator.userAgent)` though, as [test()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) it returns a Boolean. – arminrosu Apr 03 '15 at 09:24
  • 5
    Paradoxically FireFox Mobile on an Samsung Galaxy Note 8 does not return Mobi and the test will return false. – Eirinn Nov 09 '15 at 09:59
  • 14
    The linked article mentions: _If 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)._ – Daniel Hanrahan Jun 09 '16 at 13:27
  • 2
    This is much better than the other suggested solutions, it should be the accepted answer i.m.o. – RNobel Feb 07 '17 at 11:26
  • 1
    I like this solution as well. Like it was mentioned earlier some Android tablets do not have "mobi" in there user agent string, but a quick fix to detect all phones and tablets might be to use the following: ```/Mobi/i.test(navigator.userAgent) || /Anroid/i.test(navigator.userAgent)```. This post suggests something like that: https://webmasters.googleblog.com/2011/03/mo-better-to-also-detect-mobile-user.html – EricL Apr 12 '17 at 23:38
  • 1
    @EricL you have a typo in `Android` in the code in your comment. – hmatt1 Apr 17 '17 at 14:53
  • 10
    Derp. Thanks. I could not edit my previous post. Here it is again:```/Mobi/i.test(navigator.userAgent) || /Android/i.test(navigator.userAgent)``` – EricL Apr 17 '17 at 20:03
  • As elegant as the other suggested solutions are, I must say this is more than likely the more practical one. It may be a moving target, but some light maintaining might still be the most suitable choice in this situation. – Erutan409 Aug 14 '17 at 15:14
  • is this solution still working? i get false positive on the current latest chrome – Fabio Nov 08 '17 at 11:49
  • This looks like the correct answer for me, upvoted. Works well, tested just now with EricL version ````/Mobi/i.test(navigator.userAgent) || /Android/i.test(navigator.userAgent)```` – Shnigi May 17 '18 at 08:32
  • 1
    To answer @Fabio this is still working correctly from what I can see. – Telarian Feb 06 '19 at 21:36
  • It doesn't support Opera. See `navigator.userAgent` output in the image. It contains "Mobile Safari": https://imgur.com/a/y42dTWI – Halil Oct 17 '19 at 06:55
  • is this still the case or is `mobi` sufficient again? – oldboy Nov 13 '20 at 07:33
  • @Halil it still works if youre trying to identify the type of device and, i guess, not which browser is it, right? – oldboy Nov 13 '20 at 07:35
96

A simple and effective one-liner:

function isMobile() { return ('ontouchstart' in document.documentElement); }

However above code doesn't take into account the case for laptops with touchscreen. Thus, I provide this second version, based on @Julian solution:

function isMobile() {
  try{ document.createEvent("TouchEvent"); return true; }
  catch(e){ return false; }
}
kenorb
  • 118,428
  • 63
  • 588
  • 624
sequielo
  • 1,404
  • 18
  • 27
82

What you are doing by wanting to detect a mobile device is getting a little too close to a "browser sniffing" concept IMO. It would likely be much better to do some feature detection. Libraries like http://www.modernizr.com/ can help with that.

For example, where is the line between mobile and non-mobile? It gets more and more blurry every day.

Bart
  • 6,378
  • 5
  • 40
  • 52
  • 3
    still, a user could want to use "jquery mobile" for those devices, whatever the supported features. – Sirber Oct 27 '11 at 20:01
  • 9
    For example, my issue with "mobile" "non-mobile" is my rollover features, I have JS set up to turn off the features, just need to detect – Sam Sussman Dec 21 '11 at 21:18
  • 1
    +1 for the last point! The clients on handheld and desktop devices are behaving more alike with every passing day. – Filip Dupanović Feb 26 '12 at 21:01
  • 5
    Still, if you want to offer a device-specific downloadable app it can be useful. – Bastes May 25 '12 at 16:31
  • 3
    It depends on the situation, I'm looking for something that will tell me if the user is on a mobile device, so that I can disable some heavy JavaScript based animations. UA sniffing would be much more appropriate than trying to 'detect' the JavaScript performance capabilities of the user's browser. – Rick Suggs Jun 01 '12 at 15:18
  • Here's an example use: You may want to detect Android devices so when you link to an APK you show a QR-code on non-android devices, but a download image on Android (since there's no point showing a QR code on the android device). – Timmmm Nov 04 '12 at 16:32
  • 9
    Mobile vs non-mobile is a very big distinction, just using "feature detection" is stupid when you're trying to cater interactions/ui for a mobile/desktop experience. Personally, I wish that there was an easy (and reliable) way to get the OS that the current browser is running in – nbsp Jan 24 '13 at 21:52
  • Modernizr is perfect for things like disabling css :hovers on devices that support touch. UA sniffing is a hack. But we've all probably done it at some point. – Chris Beck May 02 '14 at 09:11
  • Mobile devices always full-screen everything, at least the vast majority of the time (I'm sure exceptions apply). – JVE999 Jun 17 '14 at 18:17
  • 1
    We used Modernizr.touch to do mobile detection. Windows 10 has touch enabled. This doesn't work anymore (in 2017)! – wrtsprt Jan 20 '17 at 10:40
69

It's not jQuery, but I found this: http://detectmobilebrowser.com/

It provides scripts to detect mobile browsers in several languages, one of which is JavaScript. That may help you with what you're looking for.

However, since you are using jQuery, you might want to be aware of the jQuery.support collection. It's a collection of properties for detecting the capabilities of the current browser. Documentation is here: http://api.jquery.com/jQuery.support/

Since I don't know what exactly what you're trying to accomplish, I don't know which of these will be the most useful.

All that being said, I think your best bet is to either redirect or write a different script to the output using a server-side language (if that is an option). Since you don't really know the capabilities of a mobile browser x, doing the detection, and alteration logic on the server side would be the most reliable method. Of course, all of that is a moot point if you can't use a server side language :)

K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
Ender
  • 14,345
  • 8
  • 33
  • 50
  • 6
    that does not support iPads. To support iPad, look for ip(hone|od) and "|ad" - e.g. ip(hone|od|ad) – Jayson Ragasa Jul 15 '12 at 10:31
  • 3
    I just tried the javascript from detectmobilebrowser.com/, and IT IS NOT working for iPad. – Milche Patern Jun 07 '13 at 15:30
  • 3
    @MilchePatern that's because the script is faulty, use iPad instead of ipad, then it works, I had the problem on my Samsung Tab, had to use Android iso android :) – Coen Damen Jun 18 '13 at 14:56
  • 13
    There IS a jQuery version there, and it works perfectly, but for tablet detection you must add `|android|ipad|playbook|silk` as described in the [about section](http://detectmobilebrowsers.com/about) (it's by design) – cprcrack Aug 02 '13 at 20:15
  • 3
    Well yeah, a tablet is not a mobile. The site is called dectect **mobile** browsers. – Felix Eve Jan 22 '15 at 03:00
  • 3
    @FelixEve a tablet IS a mobile device, it just isn't a smartphone, so it should be detected. If you're doing CPU-intensive animations in JS, like I'm doing, you need to filter out all mobile devices, smartphones and tablets. – Ricardo Nunes Mar 20 '15 at 12:14
  • @RicardoNunes in my case I needed to detect devices that were capable of making phone calls so I was not interested in tablets. Ideally I would use feature detection however that is [not really possible](http://stackoverflow.com/questions/7429722/how-to-detect-if-device-is-capable-of-calling-and-messaging) across all devices at the moment. – Felix Eve Mar 22 '15 at 21:44
  • This does not work if you are using Chrome on your smartphone, will detect as desktop. – monteirobrena Sep 15 '15 at 17:27
  • this works very good and accurate if you're using the mobile "additions" from their ABOUT-page. – Snickbrack Mar 29 '16 at 11:36
  • it check screen size !! not working correctly! – Moshtaba Darzi Jan 18 '21 at 06:44
48

Sometimes it is desired to know which brand device a client is using in order to show content specific to that device, like a link to the iPhone store or the Android market. Modernizer is great, but only shows you browser capabilities, like HTML5, or Flash.

Here is my UserAgent solution in jQuery to display a different class for each device type:

/*** sniff the UA of the client and show hidden div's for that device ***/
var customizeForDevice = function(){
    var ua = navigator.userAgent;
    var checker = {
      iphone: ua.match(/(iPhone|iPod|iPad)/),
      blackberry: ua.match(/BlackBerry/),
      android: ua.match(/Android/)
    };
    if (checker.android){
        $('.android-only').show();
    }
    else if (checker.iphone){
        $('.idevice-only').show();
    }
    else if (checker.blackberry){
        $('.berry-only').show();
    }
    else {
        $('.unknown-device').show();
    }
}

This solution is from Graphics Maniacs http://graphicmaniacs.com/note/detecting-iphone-ipod-ipad-android-and-blackberry-browser-with-javascript-and-php/

K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
genkilabs
  • 2,742
  • 24
  • 35
  • This works great. I needed to disable a jQuery function that runs on scrolling when using an iPad or Android phone and since the various devices have differing screen widths, this was a simple solution. Thanks a ton. – Eric Allen Sep 15 '11 at 15:04
  • The only problem with using the test of Android is what about the nook which uses the android user agent – MayorMonty May 24 '14 at 23:45
  • Nice answer which shows we don't have to be feature detection fundamentalists. – Fernando Jan 09 '15 at 07:37
45

Found a solution in: http://www.abeautifulsite.net/blog/2011/11/detecting-mobile-devices-with-javascript/.

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);
    },
    any: function() {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
};

And then to verify if its a Mobile, you can test using:

if(isMobile.any()) {
   //some code...
}
Gabriel
  • 867
  • 10
  • 22
  • 1
    A solution based on the user agent works well when you can be confident the sub string relates directly to the type of device. i.e. iPad = iPad. However there are now so many different types of devices (over 25,000) that the approach isn't accurate enough for most business purposes. I founded the open source project https://51Degrees.com to provide a reliable and robust alternative. It'll work in JavaScript and also server side. All the documentation is here... https://51degrees.com/support/documentation – James Rosewell Jun 04 '15 at 14:13
  • I used above aswell, and it was working well for me, but now its not working for android 5.1 and above, is there anything changed in android 5.1 and greater? – Imran Qamer Oct 21 '16 at 12:57
  • if( isMobile.Android() ) { document.getElementById("myAnchor").setAttribute("href", "http://google.com"); } – Amranur Rahman Jan 23 '19 at 05:59
28

If by "mobile" you mean "small screen," I use this:

var windowWidth = window.screen.width < window.outerWidth ?
                  window.screen.width : window.outerWidth;
var mobile = windowWidth < 500;

On iPhone you'll end up with a window.screen.width of 320. On Android you'll end up with a window.outerWidth of 480 (though that can depend on the Android). iPads and Android tablets will return numbers like 768 so they'll get the full view like you'd want.

Chris Moschini
  • 33,398
  • 18
  • 147
  • 176
  • 2
    why isn't 'window.screen.width' enough? Seems like you're taking the smaller of either 'window.screen.width' or 'window.outerWidth'. Why do you care about 'outerWidth'? Thanks in advance for the answer! – user1330974 Nov 12 '14 at 04:05
18

You can't rely on navigator.userAgent, not every device reveals its real OS. On my HTC for example, it depends on the settings ("using mobile version" on/off). On http://my.clockodo.com, we simply used screen.width to detect small devices. Unfortunately, in some Android versions there's a bug with screen.width. You can combine this way with the userAgent:

if(screen.width < 500 ||
 navigator.userAgent.match(/Android/i) ||
 navigator.userAgent.match(/webOS/i) ||
 navigator.userAgent.match(/iPhone/i) ||
 navigator.userAgent.match(/iPod/i)) {
alert("This is a mobile device");
}
K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
Ben H
  • 31
  • 1
  • 2
16

If you use Modernizr, it is very easy to use Modernizr.touch as mentioned earlier.

However, I prefer using a combination of Modernizr.touch and user agent testing, just to be safe.

var deviceAgent = navigator.userAgent.toLowerCase();

var isTouchDevice = Modernizr.touch || 
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/)  || 
deviceAgent.match(/(iemobile)/) || 
deviceAgent.match(/iphone/i) || 
deviceAgent.match(/ipad/i) || 
deviceAgent.match(/ipod/i) || 
deviceAgent.match(/blackberry/i) || 
deviceAgent.match(/bada/i));

if (isTouchDevice) {
        //Do something touchy
    } else {
        //Can't touch this
    }

If you don't use Modernizr, you can simply replace the Modernizr.touch function above with ('ontouchstart' in document.documentElement)

Also note that testing the user agent iemobile will give you broader range of detected Microsoft mobile devices than Windows Phone.

Also see this SO question

Community
  • 1
  • 1
j7my3
  • 1,017
  • 8
  • 13
  • And the same in Dart: `TouchEvent.supported`. – Kai Sellgren Aug 02 '13 at 11:26
  • `('ontouchstart' in window)` is an alternative to `Modernizr.touch`, too, https://hacks.mozilla.org/2013/04/detecting-touch-its-the-why-not-the-how/ – JVE999 Jun 17 '14 at 18:22
  • I think modernizr is a great solution! – Bobby Russell Nov 11 '15 at 22:42
  • You should really use RegEx `|` instead of many matches. You also don't need the `toLowerCase()` because you have the `i` modifier. Here: `var isTouchDevice = Modernizr.touch || /iphone|ipod|ipad|android|iemobile|iphone|ipad|ipod|blackberry|bada/i.test(navigator.userAgent);` – oriadam Dec 02 '15 at 17:03
15

In one line of javascript:

var isMobile = ('ontouchstart' in document.documentElement && /mobi/i.test(navigator.userAgent);

If the user agent contains 'Mobi' (as per MDN) and ontouchstart is available then it is likely to be a mobile device.

EDIT: Updates the regex code in response to feedback in the comments. Using regex/mobi/i the i makes it case-insensitive, and mobi matches all mobile browsers. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox

James Westgate
  • 10,385
  • 6
  • 56
  • 63
  • 2
    had to `/Mobi/.test(navigator.userAgent)` ... `match` didn't do it for me – BananaAcid Apr 11 '20 at 16:39
  • "Here is a JavaScript regular expression that will detect all mobile devices, including devices with a device id in their UA [(User-Agent)] string: `/mobi/i` The i makes it case-insensitive, and mobi matches all mobile browsers." https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox – Andrew Feb 22 '21 at 21:18
  • In my view, this is the best answer: `let isMobile = /mobi/i.test(navigator.userAgent);` – Andrew Feb 22 '21 at 21:21
14

I know this question has a lot of answers, but from what I saw nobody approaches the answer the way I would solve this.

CSS uses width (Media Queries) to determine which styles applied to the web document baseed on width. Why not use width in the JavaScript?

For instance in Bootstrap's (Mobile First) Media Queries, there exist 4 snap/break points:

  • Extra Small Devices are 768 pixels and under.
  • Small Devices range from 768 to 991 pixels.
  • Medium Devices range from 992 to 1199 pixels.
  • Large Devices are 1200 pixels and up.

We can use this to also solve our JavaScript issue as well.

First we will create a function that gets the window size and returns a value that allows us to see what size device is viewing our application:

var getBrowserWidth = function(){
    if(window.innerWidth < 768){
        // Extra Small Device
        return "xs";
    } else if(window.innerWidth < 991){
        // Small Device
        return "sm"
    } else if(window.innerWidth < 1199){
        // Medium Device
        return "md"
    } else {
        // Large Device
        return "lg"
    }
};

Now that we have the function set up, we can call it ans store the value:

var device = getBrowserWidth();

Your question was

I would like to run a different script if the browser is on a handheld device.

Now that we have the device information all that is left is an if statement:

if(device === "xs"){
  // Enter your script for handheld devices here 
}

Here is an example on CodePen: http://codepen.io/jacob-king/pen/jWEeWG

K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
Jacob King
  • 176
  • 2
  • 9
  • This worked best for me. Since I was using bootstrap for some mobile forward pages, this technique worked well to auto redirect away from a non-mobile forward (non-bootstrap) to a bootstrap page. Tip: I found one small problem in IE11 F12 tools: I had emulation turned on in F12 Dev Tools for a mobile device and it had trouble detecting the window size. I had re-sized it below the xs break point but it was detecting it as md. As soon I turned off emulating a phone and refreshed the page, it correctly detected the size and in my code I redirect away to a bootstrap page. – Jeff Mergler Feb 29 '16 at 18:53
  • That is I was looking for a while. Thank you! – DmitryBoyko Feb 23 '17 at 12:20
  • 2
    @JacobKing you said `Small Devices range from 768 to 991 pixels.` this means it should be `window.innerWidth < 992` (991 is included) the same thing for 1199 it should be < 1200 instead – medBouzid Oct 01 '17 at 23:47
13

I am surprised that no one pointed out a nice site: http://detectmobilebrowsers.com/ It has ready made code in different languages for mobile detection (including but not limited to):

  • Apache
  • ASP
  • C#
  • IIS
  • JavaScript
  • NGINX
  • PHP
  • Perl
  • Python
  • Rails

And if you need to detect the tablets as well, just check About section for additional RegEx parameter.

Android tablets, iPads, Kindle Fires and PlayBooks are not detected by design. To add support for tablets, add |android|ipad|playbook|silk to the first regex.

K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
Maksim Luzik
  • 3,953
  • 3
  • 31
  • 47
11

If found that just checking navigator.userAgent isn't always reliable. Greater reliability can be achieved by also checking navigator.platform. A simple modification to a previous answer seems to work better:

if (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ||
   (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.platform))) {
    // some code...
}
K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
Mark
  • 649
  • 10
  • 16
  • 7
    Arbitrarily downvoting an answer without leaving a comment shouldn't be allowed. At best, it's rude. – Mark Mar 31 '18 at 22:10
11

If you're not particularly worried about small displays you could use width/height detection. So that way if width is under a certain size, the mobile site is thrown up. It may not be the perfect way, but it will probably be the easiest to detect for multiple devices. You may need to put in a specific one for the iPhone 4 (large resolution).

MoDFoX
  • 2,094
  • 2
  • 18
  • 22
9

To add an extra layer of control I use the HTML5 storage to detect if it is using mobile storage or desktop storage. If the browser does not support storage I have an array of mobile browser names and I compare the user agent with the browsers in the array.

It is pretty simple. Here is the function:

// 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
    mobile = ['iphone','ipad','android','blackberry','nokia','opera mini','windows mobile','windows phone','iemobile','tablet','mobi']; 
    var ua=navigator.userAgent.toLowerCase();
    for (var i in mobile) if (ua.indexOf(mobile[i]) > -1) return true;

    // nothing found.. assume desktop
    return false;
}
tormuto
  • 530
  • 5
  • 14
Rasmus Søborg
  • 3,292
  • 4
  • 27
  • 44
  • 1
    your assumption based on localStorage is quite interesting, can you provide a range of supported device or browsers that correctly match your script? I'm interested in [finding a solution for this question](http://stackoverflow.com/questions/16873883/detect-max-video-resolution-support-for-a-mobile-device-on-responsive-website) I asked, and trying to detect mobile-tablet browsers can indeed be an interesting workaround – Gruber Jun 01 '13 at 17:08
9

I advise you check out http://wurfl.io/

In a nutshell, if you import a tiny JavaScript file:

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

You will be left with a JSON object that looks like:

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

(That's assuming you are using a Nexus 7, of course) and you will be able to do things like:

if(WURFL.is_mobile) {
    //dostuff();
}

This is what you are looking for.

Disclaimer: I work for the company that offers this free service.

K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
Luca Passani
  • 886
  • 7
  • 16
  • Wurfl failed detecting nexus7 and iPad mini! – Jacob Apr 03 '14 at 12:53
  • Something isn't right about the Nexus 7. Are you sure you didn't have the Nexus spoof the UA string in the settings? as far as iPad mini is concerned, yes, that's very hard to distinguish from the other iPad, but it was still recognised as an iPad, right? Is it you that downvoted my post? – Luca Passani Apr 03 '14 at 13:48
  • No, the ipad mini was detected as a desktop device – Jacob Apr 03 '14 at 13:50
9

Great answer thanks. Small improvement to support Windows phone and Zune:

if (navigator.userAgent.match(/Android/i) ||
  navigator.userAgent.match(/webOS/i) ||
  navigator.userAgent.match(/iPhone/i) ||
  navigator.userAgent.match(/iPad/i) ||
  navigator.userAgent.match(/iPod/i) ||
  navigator.userAgent.match(/BlackBerry/) ||
  navigator.userAgent.match(/Windows Phone/i) ||
  navigator.userAgent.match(/ZuneWP7/i)
) {
  // some code
  self.location = "top.htm";
}
Narendra
  • 4,264
  • 2
  • 17
  • 35
Victor Juri
  • 857
  • 9
  • 5
  • I would say this is the simplest (maybe not best) fix if you are trying to handle hover/dragging events for mobile devices. I use something like this to create a "isMobile" boolean that is then checked for every hover/mouseover event. Thats my two cents, anyways. Adding more js libraries or code that requires user interaction doesn't make too much sense to me; correct me if I am wrong though. – MeanMatt Mar 01 '12 at 00:54
  • 3
    Since you're using regular expressions, actually use them: `if (navigator.userAgent.match(/Android|webOS|iPhone|iPad|etc/)){self.location = "top.htm"}` – foobarbecue Aug 10 '19 at 22:55
8

You can use media query to be able to handle it easily.

isMobile = function(){
    var isMobile = window.matchMedia("only screen and (max-width: 760px)");
    return isMobile.matches ? true : false
}
nescafe
  • 157
  • 3
  • 12
  • 1
    I like this approach, I lifted `window.matchMedia("(pointer:coarse)").matches;` from a different answer. – Jason Lydon Feb 13 '20 at 16:45
  • This is my preferred approach since what I care about is the size of the screen/viewport and not whether or not the device is mobile since we know that mobile device sizes vary greatly and browser windows can be made very small even on large monitors. With that in mind, the better name might be `isSmallScreen` but that's just my preference. – Christopher King Dec 04 '20 at 14:36
7

Check out this post, it gives a really nice code snippet for what to do when touch devices are detected or what to do if touchstart event is called:

$(function(){
  if(window.Touch) {
    touch_detect.auto_detected();
  } else {
    document.ontouchstart = touch_detect.surface;
  }
}); // End loaded jQuery
var touch_detect = {
  auto_detected: function(event){
    /* add everything you want to do onLoad here (eg. activating hover controls) */
    alert('this was auto detected');
    activateTouchArea();
  },
  surface: function(event){
    /* add everything you want to do ontouchstart here (eg. drag & drop) - you can fire this in both places */
    alert('this was detected by touching');
    activateTouchArea();
  }
}; // touch_detect
function activateTouchArea(){
  /* make sure our screen doesn't scroll when we move the "touchable area" */
  var element = document.getElementById('element_id');
  element.addEventListener("touchstart", touchStart, false);
}
function touchStart(event) {
  /* modularize preventing the default behavior so we can use it again */
  event.preventDefault();
}
Safran Ali
  • 4,359
  • 9
  • 37
  • 57
  • `'ontouchstart' in document.documentElement` is probably a better test for touch support than `window.Touch`. Even better, use Modernizr.js (http://modernizr.com) because have spent a lot of thought trying to get touch detection right. You can see their touch detection code in http://modernizr.com/downloads/modernizr.js if you view the development code and search on "touch". – robocat Sep 13 '12 at 01:44
  • 3
    Touch detection has gotten me into trouble, because some new Windows 8 laptops detect as touchscreens in Chrome, leading to odd results. – JWarner May 02 '14 at 17:12
6

All answers use user-agent to detect the browser but device detection based on user-agent is not very good solution, better is to detect features like touch device (in new jQuery they remove $.browser and use $.support instead).

To detect mobile you can check for touch events:

function is_touch_device() {
  return 'ontouchstart' in window // works on most browsers 
      || 'onmsgesturechange' in window; // works on ie10
}

Taken from What's the best way to detect a 'touch screen' device using JavaScript?

Community
  • 1
  • 1
jcubic
  • 51,975
  • 42
  • 183
  • 323
  • 5
    Unfortunately, this is not reliable and anyway it returns `true` on desktop PCs with touchscreens. http://www.stucox.com/blog/you-cant-detect-a-touchscreen/ – JustAMartin May 20 '14 at 07:03
  • 2
    Don't forget laptops with touchscreens and full browser experiences. :-) – Mike Kormendy Jul 13 '15 at 05:17
  • this may not be the way to go to check whether it's a mobile-device or not but as the name of your function states it's perfect to check for touch-enabled devices. +1 from me ;-) – Kathara Jun 25 '19 at 13:55
6

I would be suggesting to use following combo of strings, to check if device type being used.

As per Mozilla documentation string Mobi is recommended. But, some of the old tablets doesn't return true if only Mobi is used, hence we should use Tablet string too.

Similarly, for being on the safe side iPad and iPhone strings could also be used to check the device type.

Most of the new devices would return true for Mobi string alone.

if (/Mobi|Tablet|iPad|iPhone/.test(navigator.userAgent)) {
    // do something
}
Sanjay Joshi
  • 1,542
  • 6
  • 27
  • 44
  • 4
    I had to add "android" in there to get working on tablets. I'll have to tweak but I like the approach. – Andy May 04 '17 at 03:18
6

Here's a function you can use to get a true/false answer as to whether you're running on a mobile browser. Yes, it is browser-sniffing, but sometimes that is exactly what you need.

function is_mobile() {
    var agents = ['android', 'webos', 'iphone', 'ipad', 'blackberry'];
    for(i in agents) {
        if(navigator.userAgent.match('/'+agents[i]+'/i')) {
            return true;
        }
    }
    return false;
}
Jonathon Hill
  • 3,047
  • 1
  • 31
  • 30
  • 1
    That will fail to detect many mobile browsers, especially mobile Chrome. It will also probably fail on some of: Opera Mobile, Firefox mobile, Opera Mini, various popular Chinese mobile browsers, etc etc. – robocat Sep 13 '12 at 01:37
  • You don't need `for` for this! +You forgot to create a RegExp. Here's a simpler one: `return !!navigator.userAgent.match(new RegExp(agents.join('|'),'i'))` – oriadam Dec 02 '15 at 17:09
5

Use this:

/**  * jQuery.browser.mobile (http://detectmobilebrowser.com/)  * jQuery.browser.mobile will be true if the browser is a mobile device  **/ (function(a){jQuery.browser.mobile=/android.+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|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|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|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|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|xda(\-|2|g)|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))})(navigator.userAgent||navigator.vendor||window.opera);

Then use this:

if(jQuery.browser.mobile)
{
   console.log('You are using a mobile device!');
}
else
{
   console.log('You are not using a mobile device!');
}
NCoder
  • 281
  • 3
  • 10
  • 25
5

Simple function based on http://detectmobilebrowser.com/

function isMobile() {
    var a = 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|phone)|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));
}
lucasls
  • 1,032
  • 8
  • 6
5

I know this old question and there is a lot of answer but I think this function is simple and will help for detect all mobile, Tablet and computer browser it work like a charm.

function Device_Type() 
{
    var Return_Device; 
    if(/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|phone|android|iemobile|w3c|acs\-|alav|alca|amoi|audi|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd\-|dang|doco|eric|hipt|inno|ipaq|java|jigs|kddi|keji|leno|lg\-c|lg\-d|lg\-g|lge\-|maui|maxo|midp|mits|mmef|mobi|mot\-|moto|mwbp|nec\-|newt|noki|palm|pana|pant|phil|play|port|prox|qwap|sage|sams|sany|sch\-|sec\-|send|seri|sgh\-|shar|sie\-|siem|smal|smar|sony|sph\-|symb|t\-mo|teli|tim\-|tosh|tsm\-|upg1|upsi|vk\-v|voda|wap\-|wapa|wapi|wapp|wapr|webc|winw|winw|xda|xda\-) /i.test(navigator.userAgent))
    {
        if(/(tablet|ipad|playbook)|(android(?!.*(mobi|opera mini)))/i.test(navigator.userAgent)) 
        {
            Return_Device = 'Tablet';
        }
        else
        {
            Return_Device = 'Mobile';
        }
    }
    else if(/(tablet|ipad|playbook)|(android(?!.*(mobi|opera mini)))/i.test(navigator.userAgent)) 
    {
        Return_Device = 'Tablet';
    }
    else
    {
        Return_Device = 'Desktop';
    }

    return Return_Device;
}
K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
Mohamad Hamouday
  • 1,024
  • 14
  • 17
5
<script>
  function checkIsMobile(){
      if(navigator.userAgent.indexOf("Mobile") > 0){
        return true;
      }else{
        return false;
      }
   }
</script>

If you goto any browser and if you try to get navigator.userAgent then we'll be getting the browser information something like following

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36

The same thing if you do in mobile you'll be getting following

Mozilla/5.0 (Linux; Android 8.1.0; Pixel Build/OPP6.171019.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Mobile Safari/537.36

Every mobile browser will have useragent with string containing "Mobile" So I'm using above snippet in my code to check whether current user agent is web/mobile. Based on the result I'll be doing required changes.

K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
Vishnu Prasanth G
  • 845
  • 10
  • 11
4

I use this

if(navigator.userAgent.search("mobile")>0 ){
         do something here
}
Rich
  • 3,751
  • 2
  • 23
  • 43
Yene Mulatu
  • 2,128
  • 1
  • 14
  • 12
4

This is my code I'm using in my projects:

function isMobile() {
 try {
    if(/Android|webOS|iPhone|iPad|iPod|pocket|psp|kindle|avantgo|blazer|midori|Tablet|Palm|maemo|plucker|phone|BlackBerry|symbian|IEMobile|mobile|ZuneWP7|Windows Phone|Opera Mini/i.test(navigator.userAgent)) {
     return true;
    };
    return false;
 } catch(e){ console.log("Error in isMobile"); return false; }
}
K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
Kousha
  • 973
  • 8
  • 17
4

How about mobiledetect.net?

Other solutions seem too basic. This is a lightweight PHP class. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment. You can also benefit from Mobile Detect by using any of the 3rd party plugins available for: WordPress, Drupal, Joomla, Magento, etc.

K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
3

This seems to be a comprehensive, modern solution:

https://github.com/matthewhudson/device.js

It detects several platforms, smartphone vs. tablets, and orientation. It also adds classes to the BODY tag so detection takes place only once and you can read what device you're on with a simple series of jQuery hasClass functions.

Check it out...

[DISCLAIMER: I've got nothing to do with the person who wrote it.]

Paolo Mioni
  • 990
  • 8
  • 17
  • +1 for the small and neat device.js. But I wouldn't exactly call it a "modern solution", at it's core it uses [user agent](https://github.com/matthewhudson/device.js/blob/e485d719b3a88ba96c331ee01efa712148b5f259/src/device.coffee#L18) sniffing. I also wouldn't call it "comprehensive", [ua-parser](https://github.com/tobie/ua-parser) on the other hand is. – Anthony Hatzopoulos Sep 13 '14 at 16:59
3

I know it's very old question about this kind of detection.

My solution is based on scroller width (is exist or not).

// this function will check the width of scroller
// if scroller width is less than 10px it's mobile device

//function ismob() {
    var dv = document.getElementById('divscr');
    var sp=document.getElementById('res');
    if (dv.offsetWidth - dv.clientWidth < 10) {sp.innerHTML='Is mobile'; //return true; 
    } else {
    sp.innerHTML='It is not mobile'; //return false;
    }
//}
<!-- put hidden div on very begining of page -->
<div id="divscr" style="position:fixed;top:0;left:0;width:50px;height:50px;overflow:hidden;overflow-y:scroll;z-index:-1;visibility:hidden;"></div>
<span id="res"></span>
nelek
  • 3,442
  • 3
  • 20
  • 33
  • I like this solution, are there any reason why we shouldn't use this? – James Jan 27 '20 at 11:47
  • Absolutely BRILLIANT! And it's totally cross-browser. Thank you! Edit: it's better to check for `(dv.offsetWidth - dv.clientWidth) == 0` because the scrollbar gets smaller than 10px if the window is zoomed in, which is the case in most modern laptops with high resolution but small screen (ie. 4k resolution on a 15.6 inch screen) – Ivan May 03 '20 at 07:51
  • what a unique solution. i havent seen this anywhere else yet. i can see this running into issues whereby the scrollbar is hidden (e.g. `::-webkit-scrollbar { display: none }`) has anybody tested that yet? – oldboy Nov 13 '20 at 07:44
  • @oldboy try to set visible `scrollbar` for `div` (`id="divscr")`. I don't use chrome and doesn't want install it just for testing purpose. Anyone? – nelek Jan 05 '21 at 07:39
3

The screen may be on desktop with a small resolution or a mobile with a wide resolution, as so, combining two answers found here in this question

const isMobile = window.matchMedia("only screen and (max-width: 760px)");
if (/Mobi|Tablet|iPad|iPhone/i.test(navigator.userAgent) || isMobile.matches) {
    console.log('is_mobile')
}
Diego Favero
  • 1,613
  • 2
  • 20
  • 30
2

You could also use server side script and set javascript variables from it.

Example in php

download http://code.google.com/p/php-mobile-detect/ and then set javascript variables.

<script>
//set defaults
var device_type = 'desktop';
</script>

<?php
require_once( 'Mobile_Detect.php');
$detect = new Mobile_Detect();
?>

<script>
device_type="<?php echo ($detect->isMobile() ? ($detect->isTablet() ? 'tablet' : 'mobile') : 'desktop'); ?>";
alert( device_type);
</script>
Pawel Dubiel
  • 14,123
  • 3
  • 37
  • 54
2

Also I recommend using the tiny JavaScript library Bowser, yes no r. It is based on the navigator.userAgent and quite well tested for all browsers including iPhone, Android etc.

https://github.com/ded/bowser

You can use simply say:

if (bowser.msie && bowser.version <= 6) {
  alert('Hello China');
} else if (bowser.firefox){
  alert('Hello Foxy');
} else if (bowser.chrome){
  alert('Hello Silicon Valley');
} else if (bowser.safari){
  alert('Hello Apple Fan');
} else if(bowser.iphone || bowser.android){
  alert('Hello mobile');
}
K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
arikan
  • 923
  • 7
  • 6
2

You can also detect it like below

$.isIPhone = function(){
    return ((navigator.platform.indexOf("iPhone") != -1) || (navigator.platform.indexOf("iPod") != -1));

};
$.isIPad = function (){
    return (navigator.platform.indexOf("iPad") != -1);
};
$.isAndroidMobile  = function(){
    var ua = navigator.userAgent.toLowerCase();
    return ua.indexOf("android") > -1 && ua.indexOf("mobile");
};
$.isAndroidTablet  = function(){
    var ua = navigator.userAgent.toLowerCase();
    return ua.indexOf("android") > -1 && !(ua.indexOf("mobile"));
};
K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
Nur Rony
  • 6,963
  • 7
  • 34
  • 45
2

I tried some of the ways and then I decided to fill a list manually and do a simple JS check. And in the end the user has to confirm. Because some checks gave false positive or negative.

var isMobile = false;
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Opera Mobile|Kindle|Windows Phone|PSP|AvantGo|Atomic Web Browser|Blazer|Chrome Mobile|Dolphin|Dolfin|Doris|GO Browser|Jasmine|MicroB|Mobile Firefox|Mobile Safari|Mobile Silk|Motorola Internet Browser|NetFront|NineSky|Nokia Web Browser|Obigo|Openwave Mobile Browser|Palm Pre web browser|Polaris|PS Vita browser|Puffin|QQbrowser|SEMC Browser|Skyfire|Tear|TeaShark|UC Browser|uZard Web|wOSBrowser|Yandex.Browser mobile/i.test(navigator.userAgent) && confirm('Are you on a mobile device?')) isMobile = true;

Now, if you want to use jQuery to set the CSS, you could do the following:

$(document).ready(function() {
  if (isMobile) $('link[type="text/css"]').attr('href', '/mobile.css');
});

Since the borders between mobile and fixed devices become fluent and mobile browers are already powerful, checking width and user confirmation will probably be the best for the future (assuming that width in some cases will still be important). Because touches are already converted into mouse-ups and downs.

And concerning the mobile movability, I suggest you to think about Yoav Barnea's idea:

if(typeof window.orientation !== 'undefined'){...}
Community
  • 1
  • 1
Albert
  • 71
  • 1
  • 2
  • Any sort of required user confirmation for something that should be internal and not bother him in any way is a tragic user experience detail. – mystrdat May 27 '14 at 20:06
2
function isDeviceMobile(){
 var isMobile = {
  Android: function() {
      return navigator.userAgent.match(/Android/i) && navigator.userAgent.match(/mobile|Mobile/i);
  },
  BlackBerry: function() {
      return navigator.userAgent.match(/BlackBerry/i)|| navigator.userAgent.match(/BB10; Touch/);
  },
  iOS: function() {
      return navigator.userAgent.match(/iPhone|iPod/i);
  },
  Opera: function() {
      return navigator.userAgent.match(/Opera Mini/i);
  },
  Windows: function() {
      return navigator.userAgent.match(/IEMobile/i) || navigator.userAgent.match(/webOS/i) ;
  },
  any: function() {
      return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
  }
};      
 return isMobile.any()
}
mohamed-ibrahim
  • 9,510
  • 3
  • 35
  • 47
2

Adding:

In some versions of iOS 9.x, Safari does not present the "iPhone" in navigator.userAgent, but show it in navigator.platform.

var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
    if(!isMobile){
        isMobile=/iPhone|iPad|iPod/i.test(navigator.platform);
    }
K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
NikitOn
  • 408
  • 4
  • 10
2

User agent strings should not be trusted alone. Solution below will work in all situations.

function isMobile(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)));
}

and call this function:

isMobile(navigator.userAgent || navigator.vendor || window.opera)
kaxi1993
  • 3,677
  • 3
  • 24
  • 40
2

Depending on what for you want to detect mobile (meaning this suggestion won't suit everyone's needs), you might be able to achieve a distinction by looking at the onmouseenter-to-onclick millisecond difference, like I described in this answer.

WoodrowShigeru
  • 992
  • 13
  • 17
2

I use this solution and it works fine on all devices:

if (typeof window.orientation !== "undefined" || navigator.userAgent.indexOf('IEMobile') !== -1) {
   //is_mobile
}
Pinonirvana
  • 617
  • 1
  • 5
  • 9
  • 1
    I was considering this but then I thought about when a user requests the desktop site from the chrome menu, this is done through the User-Agent string and would no longer work. – Gaby_64 May 15 '20 at 19:00
2

You could do simple thing very simple like this

(window.screen.width < 700) {
    //The device is a Mobile
} else {
    //The device is a Desktop
}
Tyler2P
  • 1,391
  • 1
  • 9
  • 18
1

http://www.w3schools.com/jsref/prop_nav_useragent.asp

Filter by platform name.

Ex:

x = $( window ).width();

platform = navigator.platform;

alert(platform);

if ( (platform != Ipad) || (x < 768) )  {


} 

^^

Allan Pereira
  • 2,551
  • 4
  • 18
  • 26
1

Checkout http://detectmobilebrowsers.com/ which provides you script for detecting mobile device in variety of languages including

JavaScript, jQuery, PHP, JSP, Perl, Python, ASP, C#, ColdFusion and many more

K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
Akshay Khale
  • 7,087
  • 7
  • 43
  • 51
1

If by a mobile device you understand a touchable one, then you can determine it by checking existence of touch handlers:

let deviceType = (('ontouchstart' in window)
                 || (navigator.maxTouchPoints > 0)
                 || (navigator.msMaxTouchPoints > 0)
                 ) ? 'touchable' : 'desktop';

jQuery is not needed for it.

Daniel Kucal
  • 6,651
  • 3
  • 33
  • 52
1

Here is one more suggestion implemented with pure JavaScript (es6)

const detectDeviceType = () =>
    /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
        ? 'Mobile'
        : 'Desktop';

detectDeviceType();
K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
Gor
  • 1,175
  • 10
  • 6
  • absolutely no need for [`arrow-syntax`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) function. – mrReiha Jul 23 '19 at 01:19
1

Utilized previously mentioned sequielo solution and added the function for width/height check (to avoid screen rotation mistake). For selecting min/max borders for mobile viewport, I use this resource https://www.mydevice.io/#compare-devices

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

function deviceType() {
    var width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
    var height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0),screenType;
    if (isMobile()){
        if ((width <= 650 && height <= 900) || (width <= 900 && height <= 650))
            screenType = "Mobile Phone";
        else
            screenType = "Tablet";
    }
    else
        screenType = "Desktop";
  return screenType;
}
Twil
  • 97
  • 12
  • is there any reason to try creating a touch event instead of checking if `touchstart` exists? – oldboy Nov 13 '20 at 07:43
1

An ES6 solution that uses several detection techniques within a try/catch block

The function consists of creating a "TouchEvent", seeking support for the "ontouchstart" event or even making a query to the mediaQueryList object.

Purposely, some queries that fail will throw a new error because as we are in a try/catch block we can use it as a fall back to consult the user agent.

I have no usage tests and in many cases it can fail as well as point out false positives.

It should not be used for any kind of real validation but, in a general scope for analysis and statistics where the volume of data can "forgive" the lack of precision, it may still be useful.

const isMobile = ((dc, wd) => {
    // get browser "User-Agent" or vendor ... see "opera" property in `window`
    let ua = wd.userAgent || wd.navigator.vendor || wd.opera;
    try {
        /**
         * Creating a touch event ... in modern browsers with touch screens or emulators (but not mobile) does not cause errors.
         * Otherwise, it will create a `DOMException` instance
         */
        dc.createEvent("TouchEvent");

        // check touchStart event
        (('ontouchstart' in wd) || ('ontouchstart' in dc.documentElement) || wd.DocumentTouch && wd.document instanceof DocumentTouch || wd.navigator.maxTouchPoints || wd.navigator.msMaxTouchPoints) ? void(0) : new Error('failed check "ontouchstart" event');

        // check `mediaQueryList` ... pass as modern browsers
        let mQ = wd.matchMedia && matchMedia("(pointer: coarse)");
        // if no have, throw error to use "User-Agent" sniffing test
        if ( !mQ || mQ.media !== "(pointer: coarse)" || !mQ.matches ) {
            throw new Error('failed test `mediaQueryList`');
        }

        // if there are no failures the possibility of the device being mobile is great (but not guaranteed)
        return true;
    } catch(ex) {
        // fall back to User-Agent sniffing
        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(ua) || /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(ua.substr(0,4));
    }
})(document, window);


// to show result
let container = document.getElementById('result');

container.textContent = isMobile ? 'Yes, your device appears to be mobile' : 'No, your device does not appear to be mobile';
<p id="result"></p>

The regex used to test the user agent is a little old and was available on the website http://mobiledetect.com which is no longer in operation.

Maybe there is a better pattern but, I don't know.


Fonts:


PS:

As there is no way to identify with 100% accuracy neither by checking features, nor by examining the user agent string with regular expressions. The code snippet above should be seen only as: "one more example for this issue", as well as: "not recommended for use in production".

Lauro Moraes
  • 1,009
  • 1
  • 10
  • 15
1
var device = {
  detect: function(key) {
    if(this['_'+key] === undefined) {
      this['_'+key] = navigator.userAgent.match(new RegExp(key, 'i'));
    }
    return this['_'+key];
  },
  iDevice: function() {
    return this.detect('iPhone') || this.detect('iPod');
  },
  android: function() {
    return this.detect('Android');
  },
  webOS: function() {
    return this.detect('webOS');
  },
  mobile: function() {
    return this.iDevice() || this.android() || this.webOS();
  }
};

I've used something like this in the past. This is similar to a previous response, but it's technically more performant in that it caches the result of the match, especially if the detection is being used in an animation, scroll event, or the like.

Fran
  • 81
  • 2
0

These are all of the vaules I am aware of. Please help udating the array if you know of any other values.

function ismobile(){
   if(/android|webos|iphone|ipad|ipod|blackberry|opera mini|Windows Phone|iemobile|WPDesktop|XBLWP7/i.test(navigator.userAgent.toLowerCase())) {
       return true;
   }
   else
    return false;
}
Kareem
  • 4,110
  • 37
  • 34
0

Ya'll are doing way too much work.

if (window.screen.availWidth <= 425) {
   // do something
}

You can do this on page load through JS. No need to write long string lists to try and catch everything. Whoops, you missed one! Then you have to go back and change it/add it. The more popular phone sizes are about 425 in width or less (in portrait mode), tablets are around 700 ish and anything bigger is likely a laptop, desktop, or other larger device. If you need mobile landscape mode, maybe you should be working in Swift or Android studio and not traditional web coding.

Side note: This may not have been an available solution when it was posted but it works now.

Sir Papilonius
  • 113
  • 1
  • 1
  • 10
0

This is what I do:

function checkMobile() {
  var os = GetOS();
  if (os == "Android OS" || os == "iOS") {
     // do what you wanna do
     return true
  }
}

and to redirect I add location.href="mobile.website.com" and then add this body tag

<body onload="checkMobile()"></body>
-1

I do this for my .NET applications.

In my shared _Layout.cshtml Page, I add this.

@{
    var isMobileDevice = HttpContext.Current.Request.Browser.IsMobileDevice;
}

<html lang="en" class="@((isMobileDevice)?"ismobiledevice":"")">

Then to check on any page in your site (jQuery):

<script>
var isMobile = $('html').hasClass('ismobiledevice');
</script>
K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
Mickey
  • 55
  • 7
-1

Just copy the following function and it returns a boolean value. its regex is looks like the marked answer but it is has some difference:

const isMobile = () =>
  /(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([46])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([ev])w|bumb|bw-([nu])|c55\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do([cp])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-([mpt])|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c([- _agpst])|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac([ \-/])|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja([tv])a|jbro|jemu|jigs|kddi|keji|kgt([ /])|klon|kpt |kwc-|kyo([ck])|le(no|xi)|lg( g|\/([klu])|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([- ov])|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30([02])|n50([025])|n7(0([01])|10)|ne(([cm])-|on|tf|wf|wg|wt)|nok([6i])|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan([adt])|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([-01])|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([im])|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)
  );
AmerllicA
  • 15,720
  • 11
  • 72
  • 103
-2

If you want to test the user agent, the correct way is to, test the user agent, i.e. test navigator.userAgent.

If the user fakes this they are not due concern. If you test.isUnix() you should not subsequently have to worry if the system is Unix.

As a user changing userAgent is also fine, but you don't expect sites to render properly if you do.

If you wish to provide support for Microsoft browsers you should ensure the first few characters of the content includes and test every page you write.

Bottom line... Always code to the standards. Then hack it until it works in the current version of IE & don't expect it to look good. That's what GitHub does, and they just got given 100 million bucks.

K.Dᴀᴠɪs
  • 9,384
  • 11
  • 31
  • 39
teknopaul
  • 5,762
  • 2
  • 26
  • 18
-4

Use this

if( screen.width <= 480 ) { 
    // is mobile 
}
Chuck Le Butt
  • 43,669
  • 58
  • 179
  • 268
sainanky
  • 503
  • 3
  • 12
  • 2
    ...and what happens if I have my desktop browser less than 480 in size? Why 480 anyway. I'd imagine there are phones when in landscape are wider than 480. – Liam Aug 02 '17 at 12:33
-4

Crude, but sufficient for restricting loading larger resources such as video files on phones vs tablet/desktop - simply look for small width or height to cover both orientations. Obviously, if the desktop browser has been resized the below could erroneously detect a phone, but that's fine / close enough for my use case.

Why 480, bcs that's what looks about right based on the info I've found re phone device dimensions.

if(document.body.clientWidth < 480 || document.body.clientHeight < 480) {
  //this is a mobile device
}
Ronnie Royston
  • 11,959
  • 5
  • 57
  • 72