JavaScript中的iPad版本检测

12

2
在该链接中,Mobile/8F190令牌是否会因iPad2而增加1?这是一个可以搜索的问题。 - Alex K.
似乎iPad 1、2和3之间确实存在差异,正如Alex和其他人在这里指出的那样,“Mobile”字符串也有所不同。 - Philipp Lenssen
1
不要忘记iPad 3! - Charlie
9个回答

12

请尝试这个示例。它通过检测陀螺仪的可用性来确定iPad的版本。

正如您在Safari开发者文库中所看到的那样,event.acceleration在具有陀螺仪的设备上不为空。由于iPad 1没有陀螺仪,因此我们可以假设该设备是iPad 1。

要区分iPad 2和iPad 3,我们可以检查window.devicePixelRatio属性,因为iPad 3具有像素比为2的Retina显示屏。


1
欢迎来到 Stack Overflow!虽然这个回答在理论上是正确的,但最好还是在此处包含答案的关键部分,并提供参考链接。 - Shawn Chin
2
有些安卓手机不喜欢这个脚本,浏览器会卡住。 - pomber
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Frogmouth

5

虽然有点晚了,但是通过使用 WEBGL_debug_renderer_info 扩展,该扩展是 WebGL API 的一部分,您可以检索GPU的供应商和渲染器名称。

将此与设备的屏幕尺寸结合起来,您可以准确地定义它是哪个版本。

// iPad model checks.
function getiPadModel(){
    // Create a canvas element which can be used to retreive 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);
            }
        }
    }    

if(window.screen.height / window.screen.width == 1024 / 768) {
    // iPad, iPad 2, iPad Mini
    if (window.devicePixelRatio == 1) {
        switch(renderer) {
            default:
                return "iPad, iPad 2, iPad Mini";
            case "PowerVR SGX 535":
                return "iPad"
            case "PowerVR SGX 543":
                return "iPad 2 or Mini";
        }
    // iPad 3, 4, 5, Mini 2, Mini 3, Mini 4, Air, Air 2
    } else {
        switch(renderer) {
            default:
                return "iPad 3, 4, 5, Mini 2, Mini 3, Mini 4, Air, Air 2";
            case "PowerVR SGX 543":
                return "iPad 3";
            case "PowerVR SGX 554":
                return "iPad 4";
            case "Apple A7 GPU":
                return "iPad Air, Mini 2, Mini 3";
            case "Apple A8X GPU":
                return "iPad Air 2";
            case "Apple A8 GPU":
                return "iPad Mini 4";
            case "Apple A9 GPU":
                return "iPad 5, Pro 9.7";
        }
    }
// iPad Pro 10.5
} else if (window.screen.height / window.screen.width == 1112 / 834) {
    return "iPad Pro 10.5";
// iPad Pro 12.9, Pro 12.9 (2nd Gen)
} else if (window.screen.height / window.screen.width == 1366/ 1024) {
    switch(renderer) {
        default:
            return "iPad Pro 12.9, Pro 12.9 (2nd Gen)";
        case "Apple A10X GPU":
            return "iPad Pro 12.9 (2nd Gen)";
        case "Apple A9 GPU":
            return "iPad Pro 12.9";
    }
} else {
    return "Not an iPad";
}
}

这项技术也可用于iPhone型号,在这篇博客中有更详细的介绍。


5
抱歉,iPad和iPad 2目前没有区别。
可以看到,两者之间没有差别:
iPad:
 Mozilla/5.0 (iPad; U; CPU OS 4_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F190 Safari/6533.18.5

iPad2:
 Mozilla/5.0 (iPad; U; CPU OS 4_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F191 Safari/6533.18.5

请注意,iOS更新中的版本在不断变化。

更新

看起来它们之间确实存在差异:

iPad:
  Mobile/8F190

iPad 2:
  Mobile/8F191

iPad 3:
  Mobile/9B176 (according to Philipp)

有一个区别:Mobile/8F190和Mobile/8F191(我不知道它是否是可靠的区别,可能是)。 - Philipp Lenssen
嗯,我之前没有注意到这个……好吧,也许你是对的! - Derek 朕會功夫
1
感谢您更新帖子!我碰巧有一台iPad 3,这是我看到的User Agent字符串的一部分:Mobile/9B176 - Philipp Lenssen
仅供更新,我正在iPad 1上进行测试,使用的是5.1.1版本,并获得了“Mobile/9B206”的移动版本。在iPad上,如果您转到“设置”-->“通用”,并查看版本,则也可以在那里看到该字符串。 - Paul Sham
这不是可靠的东西:我可以在iPad2上看到Mobile/8J2,而在iPad1上看到Mobile/9A405。因此,不同的iOS版本(因此Safari)会在相同的iPad版本上发出不同的UA警报。请转移到功能检测。 - Arman
关于“Mobile/XXXX”检测:这是一个移动版Safari构建。iPad3/iOS7有另一个构建。 - Alex

2
检测iPad 1和2的步骤:
  1. 检查UA字符串是否包含iPad
  2. 检查是否有陀螺仪
检测iPad 2和3的步骤:
  1. 检查UA字符串是否包含iPad
  2. 检查像素密度(Retina iPad 3显示器=2)
检测iPad 3和4的步骤:
  1. 检查UA字符串是否包含iPad
  2. 检查像素密度(Retina显示器=2)
  3. 检查设备的最大各向异性(iPad 3 = 2,iPad 4 = 16)
最大各向异性为16通常表示具有良好图形性能的现代设备。

var gl;
var iPadVersion = false;

window.ondevicemotion = function(event) {
  if (!iPadVersion && navigator.platform.indexOf("iPad") != -1) {
    iPadVersion = 1;
    if (event.acceleration) iPadVersion = window.devicePixelRatio;
  }
  window.ondevicemotion = null;
}

function initWebGL(canvas) {
  gl = null;

  try {
    gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
  }
  catch(e) {}

  if (!gl) {
    gl = null;
  }

  return gl;
}

function checkMaxAnisotropy() {
  var max = 0;

  var canvas = document.getElementById('webGLCanvasTest');
  gl = initWebGL(canvas);

  try {
    gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
  }
  catch(e) {}

  if (gl) {
    var ext = (
      gl.getExtension('EXT_texture_filter_anisotropic') ||
      gl.getExtension('MOZ_EXT_texture_filter_anisotropic') ||
      gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic')
    );

    if (ext){
      max = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
    }
  }
  return max;
}

function isiPad( $window ) {
  var ua = $window.navigator.userAgent || $window.navigator.vendor || $window.opera;
  return (/iPad/).test(ua);
}


function getiPadVersion( $window ) {
  if(isiPad(window) && window.devicePixelRatio === 2) {
    if(checkMaxAnisotropy() < 4) {
      iPadVersion = 3;
    } else {
      iPadVersion = 4;
    }
  }
  return iPadVersion;
}


/* BONUS CODE 
   isSmartDevice() - Detect most mobile devices
   isOldDevice() - Detect older devices that have poor video card performance
*/

function isSmartDevice( $window ) {
  var ua = $window.navigator.userAgent || $window.navigator.vendor || $window.opera;
  return (/iPhone|iPod|iPad|Silk|Android|BlackBerry|Opera Mini|IEMobile/).test(ua);
}

function isOldDevice() {
  if(isSmartDevice(window) && window.devicePixelRatio === 1 && checkMaxAnisotropy() < 4 || isiPad( window ) && checkMaxAnisotropy() < 4) {
    return true;
  } else {
    return false;
  }
}


alert('iPad Version: ' + getiPadVersion(window) );
#webGLCanvasTest {
  width: 1px;
  height: 1px;
  position: fixed;
  top: -1px;
  left: -1px;
}
<!-- Device Testing Canvas, Hide This Somewhere -->
<canvas id="webGLCanvasTest"></canvas>


1

正如其他人已经指出的那样,这是目前使用的两个用户代理:

iPad:
 Mozilla/5.0 (iPad; U; CPU OS 4_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F190 Safari/6533.18.5

iPad2:
 Mozilla/5.0 (iPad; U; CPU OS 4_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F191 Safari/6533.18.5

但是如果你仔细观察,它们并不相同,有所区别:

  • iPad有“Mobile/8F190”
  • iPad 2有“Mobile/8F191”

所以,就是这样。


0
请勿依赖User-Agent字符串解释。
这并不可靠:我可以在iPad2上看到Mobile/8J2,而在iPad1上看到Mobile/9A405。因此,不同的iOS版本(因此Safari)会在相同的iPad版本上发出不同的UA警报。
我们应该仅使用加速功能检测;无论是客户端还是服务器端(例如WURFL acceleration等...)。

0

看起来iPad 2可以与新的iPad拥有相同的Mobile/9B176代码。也许这是由于iOS的更新引起的?

以下是我的完整iPad 2用户代理字符串:

Mozilla/5.0(iPad; CPU OS 5_1 like Mac OS X)AppleWebKit/534.46(KHTML, like Gecko)Version/5.1 Mobile/9B176 Safari/7534.48.3

我无法在已更新的iPad 3上检查。请问是否有任何区别?

(顺便说一句,如果您只想知道用户是否拥有低分辨率或高分辨率的iPad,则可以使用此技巧:https://stackoverflow.com/a/10142357/974563


0

用户代理检测可以获取Safari应用程序的版本,而不是iPad本身的版本,因为您的Web应用程序只能在浏览器环境中运行。

陀螺仪和所有其他API都是SDK API,因此它们仅适用于原生应用程序开发,而不适用于Web应用程序。


实际上,这可能会让您获得iPad版本--请参见其他答案中指出的区别。 - Philipp Lenssen
陀螺仪等API不仅仅是SDK API...也可以通过浏览器使用。 - SquareFeet

-1

这样怎么样:

// For use within normal web clients 
var isiPad = navigator.userAgent.match(/iPad/i) != null;

// For use within iPad developer UIWebView
// Thanks to Andrew Hedges!
var ua = navigator.userAgent;
var isiPad = /iPad/i.test(ua) || /iPhone OS 3_1_2/i.test(ua) || /iPhone OS 3_2_2/i.test(ua);

另外,也请查看这个:

http://davidwalsh.name/detect-ipad


2
问题是关于检测iPad的版本或代数。看起来无法通过查看userAgent来实现。 - fbrandel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接