49

This is related to the "fix" for position:fixed in older versions of iOS. However, if iOS5 or greater is installed, the fix breaks the page.

I know how to detect iOS 5: navigator.userAgent.match(/OS 5_\d like Mac OS X/i) but that won't work for iOS6 when it eventually comes around, or even iOS 5.0.1, only a 2 digit version.

So this is what I have atm.

$(document).bind("scroll", function() {
    if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i))) {
        if (navigator.userAgent.match(/OS 5_\d like Mac OS X/i)) {
    }
    else {
        changeFooterPosition();
    }
});
3
  • Have you tried feature-based detection instead of user agent sniffing? I found this but I'm not able to test it currently. Commented Dec 1, 2011 at 21:00
  • There's a script for testing by looking for support for position:fixed, but it's fairly complicated, and beyond my limited skills. And I think it would slow things down. Commented Dec 1, 2011 at 21:12
  • The problem of user agent sniffing is that http clients are often able to change their user-agent and you are hardcoding your fixes to limited number of browsers. Also the slow-down is minimal as it is something that should be executed only once and definitely not multiple times (like in event handlers). You don't need to understand that script. You don't understand everything you use in jQuery I guess :). Commented Dec 1, 2011 at 21:18

9 Answers 9

137

This snippet of code can be used to determine any version of iOS 2.0 and later.

function iOSversion() {
  if (/iP(hone|od|ad)/.test(navigator.platform)) {
    // supports iOS 2.0 and later: <http://bit.ly/TJjs1V>
    var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
    return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)];
  }
}

ver = iOSversion();

if (ver[0] >= 5) {
  alert('This is running iOS 5 or later.');
}
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for coming up with this solution! The only thing I would change: gist.github.com/rafaelrinaldi/5873671 This way I'm able to do an actual numeric comparison instead of checking the string value of the first index of my result.
In my experience, an iPod touch actually returns "iPod touch" from navigator.platform, so I use the RegExp /iP(hone|od touch|ad)/ to catch it too.
Chrome gives true for this also :( I suggest to add return -1 after the if-statement
do you know what this would return on android devices? i just added 'else return null', so hopefully that can indicate a non-ios device
Really really helpful. I was looking to catch this bug and its reason since years. Thanks!
|
11

Pumbaa80's Answer was almost 100%, he just left out one part. Some iOS release have a third digit on them.

Example

Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en_us) AppleWebKit/525.18.1 (KHTML, like Gecko)

The follow allows for that

if(/(iPhone|iPod|iPad)/i.test(navigator.userAgent)) { 
    if(/OS [2-4]_\d(_\d)? like Mac OS X/i.test(navigator.userAgent)) {  
        // iOS 2-4 so Do Something   
    } else if(/CPU like Mac OS X/i.test(navigator.userAgent)) {
        // iOS 1 so Do Something 
    } else {
        // iOS 5 or Newer so Do Nothing
    }
}

That extra bit (_\d)? allows for the possibility of a third digit in the Version number. Charlie S, That should answer your question too.

Note the else because the 1st check won't work on iOS 1. iOS 1 for the iPhone and iPod didn't include a version number in its UserAgent string.

iPhone v 1.0

Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543 Safari/419.3

iPod v1.1.3

Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/4A93 Safari/419.3

All of this can be found at the following link on Apples website here.

2 Comments

Is there anyway I can get only iOS version between 8.1.1 to 8.2, It will be much helpful if we test range between iOS version
The link to Apple's website is dead.
8

I could not really find what I was looking for, so I took ideas from this page and other pages around the net and came up with this. Hopefully others will find it useful as well.

function iOS_version() { 
    if(navigator.userAgent.match(/ipad|iphone|ipod/i)){ //if the current device is an iDevice
    var ios_info ={};
    ios_info.User_Agent=navigator.userAgent;
    ios_info.As_Reported=(navigator.userAgent).match(/OS (\d)?\d_\d(_\d)?/i)[0];
    ios_info.Major_Release=(navigator.userAgent).match(/OS (\d)?\d_\d(_\d)?/i)[0].split('_')[0];
    ios_info.Full_Release=(navigator.userAgent).match(/OS (\d)?\d_\d(_\d)?/i)[0].replace(/_/g,".");
    ios_info.Major_Release_Numeric=+(navigator.userAgent).match(/OS (\d)?\d_\d(_\d)?/i)[0].split('_')[0].replace("OS ","");
    ios_info.Full_Release_Numeric=+(navigator.userAgent).match(/OS (\d)?\d_\d(_\d)?/i)[0].replace("_",".").replace("_","").replace("OS ","");   //converts versions like 4.3.3 to numeric value 4.33 for ease of numeric comparisons
    return(ios_info);
    }
}

It allows you to get the major release and full release number either as a string or as a number for iOS.

Example User Agent String:

    Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Mobile/10B329

Usage:

var iOS=iOS_version();
console.log(iOS.Full_Release); //returns values in form of "OS 6.1.3"
console.log(iOS.Full_Release_Numeric); //returns values in form of 6.13
//useful for comparisons like if(iOS.Full_Release_Numeric >6.2)

console.log(iOS.Major_Release); //returns values in form of "OS 6"
console.log(iOS.Major_Release_Numeric); //returns values in form of 6
//useful for comparisons like if(iOS.Major_Release_Numeric >7)

console.log(iOS.As_Reported); //returns values in form of "OS 6_1_3"
console.log(iOS.User_Agent); //returns the full user agent string

In the case of the original question on this page, you could use this code in the following manner:

var iOS=iOS_version();
$(document).bind("scroll", function() {
    if(iOS){if(iOS.Major_Release_Numeric <5) {} 
    else {changeFooterPosition();}
    }
});   

Comments

4

Adding on to Pumbaa80's answer. The version string might be 4_0, 5_0_1, 4_0_4, etc., and so testing against [1-4]_/d (a single underscore and number) isn't adequate. The JavaScript below is working for me for various sub-versions of iOS 3-5:

if (/(iPhone|iPod|iPad)/i.test(navigator.userAgent)) {
    if (/OS [1-4](.*) like Mac OS X/i.test(navigator.userAgent)) {
      // iOS version is <= 4.
    } else {
      // iOS version is > 4.
    }
  }

Comments

4

Here's a bit of JS to determine iOS and Android OS version.

Tested with actual user agent strings for iOS 4.3 to 6.0.1, and Android 2.3.4 to 4.2

var userOS;    // will either be iOS, Android or unknown
var userOSver; // this is a string, use Number(userOSver) to convert

function getOS( )
{
  var ua = navigator.userAgent;
  var uaindex;

  // determine OS
  if ( ua.match(/iPad/i) || ua.match(/iPhone/i) )
  {
    userOS = 'iOS';
    uaindex = ua.indexOf( 'OS ' );
  }
  else if ( ua.match(/Android/i) )
  {
    userOS = 'Android';
    uaindex = ua.indexOf( 'Android ' );
  }
  else
  {
    userOS = 'unknown';
  }

  // determine version
  if ( userOS === 'iOS'  &&  uaindex > -1 )
  {
    userOSver = ua.substr( uaindex + 3, 3 ).replace( '_', '.' );
  }
  else if ( userOS === 'Android'  &&  uaindex > -1 )
  {
    userOSver = ua.substr( uaindex + 8, 3 );
  }
  else
  {
    userOSver = 'unknown';
  }
}

Then to detect a specific version and higher, try:

if ( userOS === 'iOS' && Number( userOSver.charAt(0) ) >= 5 ) { ... }

1 Comment

12 years later I use this option but substr is depreciated. I use substring instead but the start end must be absolute locations so like (ua.substring( uaindex + 3, uaindex + 3 + 3))
3

First: Don't use match when a test is enough.

Second: You should test the other way round. Find the UAs which are known to be broken.

if(/(iPhone|iPod|iPad)/i.test(navigator.userAgent)) {
    if (/OS [1-4]_\d like Mac OS X/i.test(navigator.userAgent)) {
        changeFooterPosition();
...

3 Comments

Third: Don't do UA test inside a handler :).
Absolutely! The $().bind() should be moved inside the if block.
The code above returns false for me when browsing with ...iPad; U; CPU OS 4_3_3 like Mac OS X.... What am I missing?
1
function getIOSVersion() {
    const ua = navigator.userAgent;
    if (/(iPhone|iPod|iPad)/i.test(ua)) {
        return ua.match(/OS [\d_]+/i)[0].substr(3).split('_').map(n => parseInt(n));
    }
    return [0];
}

This will return an array with the individual version numbers like [10,0,1] for v10.0.1, or it'll default to [0] otherwise. You can check the first digit (the major version) or all of them to test for the versions you need.

Comments

1

Just simply run this code in device/browser

    const userAgent = window.navigator.userAgent;
    if(userAgent.match( /iP(hone|od|ad)/)){
        /* userAgent = Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1 */
        
        const iphone_version = userAgent.match(/OS [\d_]+/i)[0].substr(3).replace('_', '.');
        console.log(iphone_version); // it will log 16.6
    }

This iphone_version variable will give you correct OS version for any iPhone device.

Comments

0

Further parse out the version number ("5"), then add a condition where if number is greater than / less than version number.

1 Comment

Something like? $(document).bind("scroll", function() { if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i))) { if (match = /iPhone OS (.*) like Mac OS X/.exec(navigator.userAgent)) { var version = parseInt(match[1].replace('_', ''), 10) / 100; if (version < 5) { changeFooterPosition(); } } } });

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.