我想知道是否有可能检测浏览器是否运行在iOS上,类似于你如何使用Modernizr进行功能检测(尽管这显然是设备检测而不是功能检测)。

通常情况下,我会倾向于功能检测,但我需要找出设备是否是iOS,因为他们处理视频的方式根据这个问题,YouTube API不适用于iPad / iPhone /非flash设备


当前回答

为了检测iOS版本,我们必须像这样用Javascript代码解构用户代理:

 var res = navigator.userAgent.match(/; CPU.*OS (\d_\d)/);
    if(res) {
        var strVer = res[res.length-1];
        strVer = strVer.replace("_", ".");
        version = strVer * 1;
    }

其他回答

iOS检测

在iOS 13 iPad中,用户代理和平台字符串都被改变了,iPad和MacOS之间的区别似乎是可能的,所以下面的所有回答都需要考虑到这一点。

这可能是覆盖iOS 13的最短替代方案:

function iOS() {
  return [
    'iPad Simulator',
    'iPhone Simulator',
    'iPod Simulator',
    'iPad',
    'iPhone',
    'iPod'
  ].includes(navigator.platform)
  // iPad on iOS 13 detection
  || (navigator.userAgent.includes("Mac") && "ontouchend" in document)
}

iOS要么为真,要么为假

更糟糕的选择:用户代理嗅探

用户代理嗅探更加危险,经常出现问题。

在iPad iOS 13上,用户代理与MacOS 13计算机上的用户代理相同,但如果你忽略iPad,这可能仍然可以工作一段时间:

var iOS = !window.MSStream && /iPad|iPhone|iPod/.test(navigator.userAgent); // fails on iPad iOS 13

!窗口。MSStream是为了不错误地检测IE11,请看这里和这里。

注意:都是导航器。userAgent和navigator。平台可以被用户或浏览器扩展伪造。

改变userAgent或平台的浏览器扩展存在,因为网站使用了过于繁重的检测,并且经常禁用一些功能,即使用户的浏览器本来可以使用这些功能。

为了减少与用户的冲突,建议针对每种情况专门检测您的网站需要的确切功能。然后,当用户得到一个具有所需功能的浏览器时,它就已经可以工作了,而无需额外的代码更改。

检测iOS版本

检测iOS版本的最常见方法是从User Agent字符串中解析它。但也有特征检测推断*;

我们知道,历史API是在iOS4中引入的,matchMedia API是在iOS5中引入的,webAudio API是在iOS6中引入的,WebSpeech API是在iOS7中引入的,等等。

注意:以下代码是不可靠的,如果这些HTML5功能中的任何一个在更新的iOS版本中被弃用,就会中断。我警告过你!

function iOSversion() {

  if (iOS) { // <-- Use the one here above
    if (window.indexedDB) { return 'iOS 8 and up'; }
    if (window.SpeechSynthesisUtterance) { return 'iOS 7'; }
    if (window.webkitAudioContext) { return 'iOS 6'; }
    if (window.matchMedia) { return 'iOS 5'; }
    if (window.history && 'pushState' in window.history) { return 'iOS 4'; }
    return 'iOS 3 or earlier';
  }

  return 'Not an iOS device';
}

如果您正在使用Modernizr,您可以为它添加一个自定义测试。

决定使用哪种检测模式并不重要(userAgent, navigator。Vendor或navigator.platform),您总是可以将其打包以便稍后使用。

//Add Modernizr test
Modernizr.addTest('isios', function() {
    return navigator.userAgent.match(/(iPad|iPhone|iPod)/g);
});

//usage
if (Modernizr.isios) {
    //this adds ios class to body
    Modernizr.prefixed('ios');
} else {
    //this adds notios class to body
    Modernizr.prefixed('notios');
}

没有必要测试导航器。userAgent或navigator.platform:

const isIOS = typeof navigator.standalone === 'boolean';

导航器。standalone只在iOS Safari上设置。参见MDN, Safari HTML参考。

在iOS 13之后,你应该像这样检测iOS设备,因为iPad将不会被旧的方式检测为iOS设备(由于新的“桌面”选项,默认启用):

let isIOS = /iPad|iPhone|iPod/.test(navigator.platform)
|| (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)

第一个条件适用于iOS < 13或禁用桌面模式的iPhone或iPad,第二个条件适用于默认配置的iPadOS 13,因为它将自己定位为Macintosh Intel,但实际上是唯一具有多点触摸的Macintosh。

与其说是一种破解,不如说是一种真正的解决方案,但对我来说很可靠

P.S.如前所述,你可能应该添加IE检查

let isIOS = (/iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) &&
!window.MSStream

因为导航器。平台已弃用,最好不再使用,我想添加一个其他解决方案。

你可以通过检查navigator.vendor来过滤MacOS系统。 当结果是苹果电脑公司,你知道它是MacOS。