How to determine which iPhone version the javascri

2019-01-18 23:50发布

问题:

Need to distinguish between iPhone3x and iPhone4x. Is there any way to figure out the version from JavaScript please?

回答1:

You can use navigator.userAgent to check the OS version, but that isn't really the problem here.

What you can do is use media queries to check the actual screen resolution of the device, which might be the cause of the problem at hand.

var isRetina = window.matchMedia("(-webkit-min-device-pixel-ratio: 2)").matches;

You could also probably do without JavaScript, by using media queries for loading different stylesheets for retina displays:

<link rel="stylesheet" href="retina.css"
    media="only screen and (-webkit-min-device-pixel-ratio: 2)" />


回答2:

It would be a combination of two methods in Javascript:

function iPhoneVersion() {
  var iHeight = window.screen.height;
  var iWidth = window.screen.width;

  if (iWidth === 414 && iHeight === 896) {
    return "Xmax-Xr";
  }
  else if (iWidth === 375 && iHeight === 812) {
    return "X-Xs";
  }
  else if (iWidth === 320 && iHeight === 480) {
    return "4";
  }
  else if (iWidth === 375 && iHeight === 667) {
    return "6";
  }
  else if (iWidth === 414 && iHeight === 736) {
    return "6+";
  }
  else if (iWidth === 320 && iHeight === 568) {
    return "5";
  }
  else if (iHeight <= 480) {
    return "2-3";
  }
  return 'none';
}

function isIphone() {
  return !!navigator.userAgent.match(/iPhone/i);
}

So all you need to do is test if it's an Iphone and then get the version:

if ( isIphone() && iPhoneVersion() === "6"){
  //code..
}



回答3:

By using WEBGL_debug_renderer_info extension, which is part of the WebGL API, you are able to retrieve the vendor of the GPU and the renderer name.

Combining this with screen dimensions of the device you can accurately define which version it is. The code example below shows how you can do this for all iPhone versions including 3 and 4.

    // iPhone model checks.
function getiPhoneModel() {
    // Create a canvas element which can be used to retrieve information about the GPU.
    var canvas = document.createElement("canvas");
    if (canvas) {
        var context = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
        if (context) {
            var info = context.getExtension("WEBGL_debug_renderer_info");
            if (info) {
                var renderer = context.getParameter(info.UNMASKED_RENDERER_WEBGL);
            }
        }
    }

    // iPhone X
    if ((window.screen.height / window.screen.width == 812 / 375) && (window.devicePixelRatio == 3)) {
        return "iPhone X";
    // iPhone 6+/6s+/7+ and 8+
    } else if ((window.screen.height / window.screen.width == 736 / 414) && (window.devicePixelRatio == 3)) {
        switch (renderer) {
            default:
                return "iPhone 6 Plus, 6s Plus, 7 Plus or 8 Plus";
            case "Apple A8 GPU":
                return "iPhone 6 Plus";
            case "Apple A9 GPU":
                return "iPhone 6s Plus";
            case "Apple A10 GPU":
                return "iPhone 7 Plus";
            case "Apple A11 GPU":
                return "iPhone 8 Plus";
        }
    // iPhone 6+/6s+/7+ and 8+ in zoom mode
    } else if ((window.screen.height / window.screen.width == 667 / 375) && (window.devicePixelRatio == 3)) {
        switch(renderer) {
            default:
                return "iPhone 6 Plus, 6s Plus, 7 Plus or 8 Plus (display zoom)";
            case "Apple A8 GPU":
                return "iPhone 6 Plus (display zoom)";
            case "Apple A9 GPU":
                return "iPhone 6s Plus (display zoom)";
            case "Apple A10 GPU":
                return "iPhone 7 Plus (display zoom)";
            case "Apple A11 GPU":
                return "iPhone 8 Plus (display zoom)";
        }
    // iPhone 6/6s/7 and 8
    } else if ((window.screen.height / window.screen.width == 667 / 375) && (window.devicePixelRatio == 2)) {
        switch(renderer) {
            default:
                return "iPhone 6, 6s, 7 or 8";
            case "Apple A8 GPU":
                return "iPhone 6";
            case "Apple A9 GPU":
                return "iPhone 6s";
            case "Apple A10 GPU":
                return "iPhone 7";
            case "Apple A11 GPU":
                return "iPhone 8";
        }
    // iPhone 5/5C/5s/SE or 6/6s/7 and 8 in zoom mode
    } else if ((window.screen.height / window.screen.width == 1.775) && (window.devicePixelRatio == 2)) {
        switch(renderer) {
            default:
                return "iPhone 5, 5C, 5S, SE or 6, 6s, 7 and 8 (display zoom)";
            case "PowerVR SGX 543":
                return "iPhone 5 or 5c";
            case "Apple A7 GPU":
                return "iPhone 5s";
            case "Apple A8 GPU":
                return "iPhone 6 (display zoom)";
            case "Apple A9 GPU":
                return "iPhone SE or 6s (display zoom)";
            case "Apple A10 GPU":
                return "iPhone 7 (display zoom)";
            case "Apple A11 GPU":
                return "iPhone 8 (display zoom)";
        }
    // iPhone 4/4s
    } else if ((window.screen.height / window.screen.width == 1.5) && (window.devicePixelRatio == 2)) {
        switch(renderer) {
            default:
                return "iPhone 4 or 4s";
            case "PowerVR SGX 535":
                return "iPhone 4";
            case "PowerVR SGX 543":
                return "iPhone 4s";
        }
    // iPhone 1/3G/3GS
    } else if ((window.screen.height / window.screen.width == 1.5) && (window.devicePixelRatio == 1)) {
        switch(renderer) {
            default:
                return "iPhone 1, 3G or 3GS";
            case "ALP0298C05":
                return "iPhone 3GS";
            case "S5L8900":
                return "iPhone 1, 3G";
        }
    } else {
        return "Not an iPhone";
    }
}


回答4:

I came across to a similar problem a while ago. Working on a client's website that had lots of videos loaded via javascript, I found out that the video format they needed to use had a weird frame rate that didn't work on iPhone 3GS -.

Following atornblad's approach, I got to this solution that perfectly suited what I needed:

if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))) {
    if (!(window.devicePixelRatio > 1)){
        //non retina iphone / ipod
    }
};

First it checks if the user is coming to me from an iPod or an iPhone. Then, it checks for Retina support. Since only iPhone 4+ supports it, I managed to call the correct video files for older devices.



回答5:

Something about the more CPU-speed measuring-methods: They may be an "unfit" approach here, but finding out the computing power of your target device might be useful for some cases.

So here is something I want to add to those methods: instead of counting up a fixed value and measuring the time, it would be more robust to count up for a fixed time and then compare reached values. If your user visits you on a device that is much slower, maybe because it runs inside an emulator, he will have to wait until you counted to n. if you had left the loop after, say 200ms, you would just have reaced a very low value, and the UX was not influenced.

Additionally, it's always nice to know, how long an operation will take, it reduces uncertainties.



回答6:

Maybe you can check it by taking OS version in query navigator.appVersion.indexOf("... iphone3G has Apple iOS 4.2.1 iphone4 and 4S have Apple iOS 5.0.1 but iphone3GS has the same.

As variant you can provide cpu speed test by using big loop. Something like for (var i=0, k=1; i<5000000; i++) k++; and checkin consumed time for this.

iphone3G(S) has maximum 600 Mhz, and iphone4 has 1 Ghz. So, there is a distinction, and you can to catch it after some tests (loop) and define loop speed for each iphone generation.

But note, all this ways are rough and may have been not correct in other conditions.



回答7:

The solution is actually pretty simple but longer to write than i expected.

as Yan Pak Said, the only way we can check it is by checking the CPU speed. I wrote a small loop that runs from 0 to 10000000 and then started to run it on different devices. i checked the time before, than checked the time after and of course, every device returened different result.

from the agent, we can know the device type. all is left is to separate the speeds. these are the devices i was checking it on.

iphone 4s < 200
iphone 4 <300
iphone 3gs <400

ipad 2 <200
all the rest are ipad 1

here is my code, hope it helps anybody:

var date1 = new Date();//time we started              
for (var i=0, j=1; i<10000000; i++) j++; 
var date2 = new Date();//time we ended
diff=date2.getTime() - date1.getTime(); //time difference.
alert(diff);//show me the difference so i can add lines to more phone types
if (device=='iPad' && diff<200){
    deviceVersion='2';
}
else if (device=='iPad'){
    deviceVersion='1';
}
else if (device=='iphone' && diff<200){
    deviceVersion='4s';
}
else if (device=='iphone' && diff<300){
    deviceVersion='4';
}
else if (device=='iphone' && diff<400){
    deviceVersion='3gs';
}
...

Some people might prefer switch case. i like if.