如何确定 javascript 代码在哪个 iPhone 版本上运行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8309998/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 03:00:18  来源:igfitidea点击:

How to determine which iPhone version the javascript code runs on?

javascriptmobilemobile-safari

提问by BreakPhreak

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

需要区分iPhone3xiPhone4x。请问有什么办法可以从JavaScript中找出版本吗?

采纳答案by Anders Tornblad

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

您可以使用navigator.userAgent来检查操作系统版本,但这并不是真正的问题。

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:

您也可以不用 JavaScript,通过使用媒体查询为 Retina 显示加载不同的样式表:

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

回答by Shawn Dotey

It would be a combination of two methods in Javascript:

这将是 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:

因此,您需要做的就是测试它是否是 Iphone,然后获取版本:

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

回答by Josh Grew

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.

通过使用作为WebGL API一部分的 WEBGL_debug_renderer_info 扩展,您可以检索 GPU 的供应商和渲染器名称。

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 版本(包括 3 和 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";
    }
}

回答by Fernanda Parisi

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

不久前我遇到了类似的问题。在通过 javascript 加载了大量视频的客户网站上工作时,我发现他们需要使用的视频格式具有奇怪的帧速率,在 iPhone 3GS 上不起作用 -。

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

按照 atornblad 的方法,我得到了这个非常适合我需要的解决方案:

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.

首先它检查用户是从 iPod 还是 iPhone 来找我的。然后,它会检查 Retina 支持。由于只有 iPhone 4+ 支持它,我设法为旧设备调用了正确的视频文件。

回答by tinman2501

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.

关于更多 CPU 速度的测量方法:它们在这里可能是一种“不适合”的方法,但在某些情况下找出目标设备的计算能力可能会有用。

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.

所以这里有一些我想添加到这些方法中的东西:不是计算固定值并测量时间,而是计算固定时间然后比较达到的值会更健壮。如果您的用户在速度较慢的设备上访问您,可能是因为它在模拟器内运行,他将不得不等到您数到 n。如果你在 200 毫秒之后离开循环,你只会得到一个非常低的值,并且用户体验不会受到影响。

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

此外,很高兴知道操作需要多长时间,这样可以减少不确定性。

回答by Yan Pak

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.

也许您可以通过查询navigator.appVersion.indexOf("...iphone3G has Apple iOS 4.2.1 iphone4 and 4S has Apple iOS 5.0.1 但 iphone3GS 中的操作系统版本来检查它。

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.

作为变体,您可以使用大循环提供 CPU 速度测试。像这样的东西for (var i=0, k=1; i<5000000; i++) k++;和签入为此消耗了时间。

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.

iphone3G(S) 最大600 Mhz,iphone4 1 Ghz。所以,有一个区别,你可以在一些测试(循环)后捕捉它并为每一代 iphone 定义循环速度。

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

但请注意,所有这些方法都很粗糙,在其他情况下可能不正确。