What is the best way to detect a handheld device in jQuery?-Collection of common programming errors


  • filmor

    Is there a solid way to detect whether or not a user is using a mobile/handheld 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.

  • 25 Answers


  • 7 revs, 6 users 48%sweets-BlingBling

    Instead of using jquery you can use simple javascript to detect it:

    if( /Android|webOS|iPhone|iPad|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/i.test(navigator.userAgent.toLowerCase()));
    

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

    Note: $.browser removed on jQuery v1.9.1


  • Gonçalo Peres

    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:

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

    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.


  • Bart

    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.


  • Ender

    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 🙂


  • genkilabs

    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/


  • Gabriel

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

  • MoDFoX

    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).


  • Radek

    Here’s good thing for some languages: http://detectmobilebrowsers.com/


  • Chris Moschini

    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.


  • Jonathon Hill

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

  • Safran Ali

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

  • Victor Juri

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

  • Ben H

    You can’t rely on navigator.userAgent, not every device reveales 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");
    }
    

  • Volomike

    Here’s what I use:

    if (navigator.userAgent.match(/mobile/i)) {
      // do something
    }
    

  • Fran

    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.


  • mmoscosa

  • Nur Mohammed Rony

    You can also detect it like bellow

    $.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"));
    };
    

  • dotTutorials

    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() {
        ///Detecting whether the browser is a mobile browser or desktop browser
        ///A boolean value indicating whether the browser is a mobile browser or not
    
        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']; 
        for (var i in mobile) if (navigator.userAgent.toLowerCase().indexOf(mobile[i].toLowerCase()) > 0) return true;
    
        // nothing found.. assume desktop
        return false;
    }
    

  • user2110309

    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


  • Yene Mulatu

    I use this

    if(navigator.userAgent.search("mobile")>0 ){
             do something here
    

    }


  • Arius2038

    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.

    
    //set defaults
    var device_type = 'desktop';
    
    
    
    
    
    device_type="";
    alert( device_type);
    
    

  • Mark

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

  • arikan

    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