我想知道是否可以检测浏览器是否在iOS上运行,类似于使用Modernizr进行功能检测的方式(尽管这显然是设备检测而不是功能检测)。
通常情况下我会支持功能检测,但是我需要找出设备是否是iOS,因为他们根据这个问题处理视频的方式YouTube API not working with iPad / iPhone / non-Flash device
答案 0 :(得分:709)
我不是用户代理嗅探的粉丝,但是你会这样做:
var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
另一种方法是依靠navigator.platform
:
var iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
iOS
可以是true
或false
微软在IE11的userAgent
中注入了 iPhone 这个词,试图以某种方式欺骗Gmail。因此我们需要排除它。有关此here和here的详细信息。
以下是IE11更新的userAgent
(适用于Windows Phone 8.1更新的Internet Explorer):
Mozilla / 5.0(移动版; Windows Phone 8.1; Android 4.0; ARM; Trident / 7.0; 触摸; RV:11.0; IEMobile / 11.0;诺基亚; Lumia 930)喜欢iPhone OS 7_0_3 Mac OS X AppleWebKit / 537(KHTML,如Gecko)Mobile Safari / 537
轻松添加更多设备,而不使用正则表达式:
function iOS() {
var iDevices = [
'iPad Simulator',
'iPhone Simulator',
'iPod Simulator',
'iPad',
'iPhone',
'iPod'
];
if (!!navigator.platform) {
while (iDevices.length) {
if (navigator.platform === iDevices.pop()){ return true; }
}
}
return false;
}
iOS()
可以是true
或false
注意:navigator.userAgent
和navigator.platform
都可以由用户或浏览器扩展程序伪造。
检测iOS版本的最常用方法是parsing it from the User Agent string。但是还有功能 detection 推断 *;
我们知道{em> iOS4 中引入history API
的事实 - iOS5 中的matchMedia API
- 中的webAudio API
iOS6 - iOS7 中的WebSpeech API
等等..
注意:以下代码不可靠,如果在较新的iOS版本中弃用这些HTML5功能,则会破坏以下代码。你被警告了!
function iOSversion() {
if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
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';
}
答案 1 :(得分:12)
这会将变量_iOSDevice
设置为 true 或 false
_iOSDevice = !!navigator.platform.match(/iPhone|iPod|iPad/);
答案 2 :(得分:11)
在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>
不是真正的解决方案,而是hack,但是对我来说可靠地工作
PS 。如前所述,您可能应该添加IE检查
let isIOS = (/iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) &&
!window.MSStream
答案 3 :(得分:9)
如果您使用的是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');
}
答案 4 :(得分:8)
有这种自定义Modernizr测试:https://gist.github.com/855078
答案 5 :(得分:7)
以上所有答案均不适用于所有iOS版本(包括iOS 13)上的所有主要浏览器。以下解决方案适用于所有iOS版本的Safari,Chrome和Firefox:
var isIOS = (function () {
var iosQuirkPresent = function () {
var audio = new Audio();
audio.volume = 0.5;
return audio.volume === 1; // volume cannot be changed from "1" on iOS 12 and below
};
var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
var isAppleDevice = navigator.userAgent.includes('Macintosh');
var isTouchScreen = navigator.maxTouchPoints >= 1; // true for iOS 13 (and hopefully beyond)
return isIOS || (isAppleDevice && (isTouchScreen || iosQuirkPresent()));
})();
请注意,此代码段优先考虑的是可读性,简洁性或性能。
说明:
如果用户代理包含“ iPod | iPhone | iPad”中的任何一个,则该设备显然是iOS。否则,继续...
任何其他不包含“ Macintosh”的用户代理都不是Apple设备,因此不能是iOS。否则,它是一台Apple设备,因此继续...
如果maxTouchPoints
的值为1
或更大,则Apple设备具有触摸屏,因此必须为iOS,因为没有Macs带有触摸屏(对kikiwora表示感谢) maxTouchPoints
)。请注意,maxTouchPoints
是iOS 12及更低版本的undefined
,因此我们需要针对该情况的其他解决方案...
iOS 12和更低版本的Mac OS中没有这个怪癖。奇怪的是,volume
元素的Audio
属性无法成功设置为1
以外的任何值。这是因为Apple不允许iOS设备的Audio
元素上的音量更改,但Mac OS则允许。该怪癖可以用作区分iOS设备和Mac OS设备的最终后备方法。
答案 6 :(得分:3)
iOS设备上的用户代理说iPhone或iPad。我只是根据这些关键字进行过滤。
答案 7 :(得分:3)
简化,易于扩展的版本。
var iOS = ['iPad', 'iPhone', 'iPod'].indexOf(navigator.platform) >= 0;
答案 8 :(得分:2)
在添加Modernizr测试时,您应该尽可能为功能添加测试,而不是设备或操作系统。如果需要的话,添加10个测试所有iPhone的测试都没有错。有些事情不能被检测到。
Modernizr.addTest('inpagevideo', function ()
{
return navigator.userAgent.match(/(iPhone|iPod)/g) ? false : true;
});
例如,在iPhone(不是iPad)上无法在网页上内嵌播放视频,它会全屏显示。所以我创建了一个测试&#39; no-inpage-video&#39;
然后您可以在css中使用它(如果测试失败,Modernizr会向.no-inpagevideo
标记添加一个类<html>
.no-inpagevideo video.product-video
{
display: none;
}
这会隐藏iPhone上的视频(在这种情况下我实际上正在做的是显示带有onclick播放视频的替代图像 - 我只是不想要默认的视频播放器和播放按钮显示)。
答案 9 :(得分:2)
几年前我写过这篇文章,但我相信它仍然有用:
if(navigator.vendor != null && navigator.vendor.match(/Apple Computer, Inc./) && navigator.userAgent.match(/iPhone/i) || (navigator.userAgent.match(/iPod/i)))
{
alert("Ipod or Iphone");
}
else if (navigator.vendor != null && navigator.vendor.match(/Apple Computer, Inc./) && navigator.userAgent.match(/iPad/i))
{
alert("Ipad");
}
else if (navigator.vendor != null && navigator.vendor.match(/Apple Computer, Inc./) && navigator.userAgent.indexOf('Safari') != -1)
{
alert("Safari");
}
else if (navigator.vendor == null || navigator.vendor != null)
{
alert("Not Apple Based Browser");
}
答案 10 :(得分:1)
哇,这里有很多冗长的棘手代码。请保持简单!
这是恕我直言,快速,保存并且运行良好:
iOS = /^iP/.test(navigator.platform);
// or, more future-proof (in theory, probably not in practice):
iOS = /^iP(hone|[ao]d)/.test(navigator.platform);
// or, if you prefer readability:
iOS = /^(iPhone|iPad|iPod)/.test(navigator.platform);
答案 11 :(得分:1)
社区Wiki,因为编辑队列说它已满,而所有其他答案目前已过时或不完整。
const iOS_1to12 = /iPad|iPhone|iPod/.test(navigator.platform);
const iOS13_iPad = (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1));
const iOS1to12quirk = function() {
var audio = new Audio(); // temporary Audio object
audio.volume = 0.5; // has no effect on iOS <= 12
return audio.volume === 1;
};
const isIOS = !window.MSStream && (iOS_1to12 || iOS13_iPad || iOS1to12quirk());
答案 12 :(得分:0)
使用更实用的方法来稍微更新第一个答案。
const isIOS = [
'iPad Simulator',
'iPhone Simulator',
'iPod Simulator',
'iPad',
'iPhone',
'iPod',
]
.map(device => navigator.platform === device)
.filter(device => device)
.reduce(() => true, false);
答案 13 :(得分:0)
可能值得回答的是,运行iOS 13的iPad将navigator.platform
设置为MacIntel
,这意味着您需要找到另一种检测iPadOS设备的方法。
答案 14 :(得分:0)
您也可以使用includes
const isApple = ['iPhone', 'iPad', 'iPod', 'iPad Simulator', 'iPhone Simulator', 'iPod Simulator',].includes(navigator.platform)
答案 15 :(得分:0)
无需测试 navigator.userAgent
或 navigator.platform
:
const isIOS = typeof navigator.standalone === 'boolean';
navigator.standalone
仅在 iOS Safari 上设置。见MDN、Safari HTML Reference。
答案 16 :(得分:-1)
在我的情况下,用户代理还不够好,因为在Ipad中用户代理与Mac OS中的用户代理相同,因此我不得不做一个讨厌的把戏:
var mql = window.matchMedia("(orientation: landscape)");
/**
* If we are in landscape but the height is bigger than width
*/
if(mql.matches && window.screen.height > window.screen.width) {
// IOS
} else {
// Mac OS
}
答案 17 :(得分:-2)
var isiOSSafari = (navigator.userAgent.match(/like Mac OS X/i)) ? true: false;
答案 18 :(得分:-2)
为了检测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;
}