我想知道是否有可能检测浏览器是否在iOS上运行,这与使用Modernizr进行功能检测的方式类似(尽管这显然是设备检测而非功能检测)。
通常,我宁愿使用功能检测,但我需要根据该问题确定设备是否为iOS,因为它们处理视频的方式YouTube API无法在iPad / iPhone /非Flash设备上使用
我想知道是否有可能检测浏览器是否在iOS上运行,这与使用Modernizr进行功能检测的方式类似(尽管这显然是设备检测而非功能检测)。
通常,我宁愿使用功能检测,但我需要根据该问题确定设备是否为iOS,因为它们处理视频的方式YouTube API无法在iPad / iPhone /非Flash设备上使用
Answers:
我不喜欢User Agent嗅探,但是您可以按照以下方式进行:
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中注入了iPhone一词,userAgent
以试图以某种方式欺骗Gmail。因此,我们需要排除它。关于这方面更多的信息在这里和这里。
以下是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)移动版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版本的最常见方法是通过User Agent字符串进行解析。但是也有特征检测推论* ;
我们知道,一个事实,history API
在引进的iOS4 - matchMedia API
在iOS5中 - webAudio API
在iOS6的 - WebSpeech API
在iOS7等..
注意:以下代码不可靠,如果在更新的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';
}
var iOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15
因此此答案需要更新
在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。
与其说是一个真正的解决方案,不如说是骇客,但对我来说却可靠
PS如前所述,您可能应该添加IE检查
let isIOS = (/iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) &&
!window.MSStream
navigator.userAgent
进行此检查/iPad|iPhone|iPod/.test(navigator.platform)
?似乎navigator.platform
总是为iPhone iOS <= 12返回'MacIntel'
navigator.maxTouchPoints
在iOS中不受支持,因此支票不会为您做任何事情。
如果您正在使用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');
}
return x ? true : false
到return Boolean(x)
或只是return !!x
有此自定义的Modernizr测试:https : //gist.github.com/855078
简化,易于扩展的版本。
var iOS = ['iPad', 'iPhone', 'iPod'].indexOf(navigator.platform) >= 0;
navigator.platform.replace(' Simulator', '')
。
['str'].indexOf('string') == -1
我几年前写了这篇文章,但我相信它仍然有效:
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");
}
iOS设备上的用户代理在其中说iPhone或iPad。我只是根据这些关键字进行过滤。
添加Modernizr测试时,应尽可能添加针对功能而不是设备或操作系统的测试。如果需要的话,添加十项针对iPhone的测试完全没有错。有些东西只是无法检测到。
Modernizr.addTest('inpagevideo', function ()
{
return navigator.userAgent.match(/(iPhone|iPod)/g) ? false : true;
});
例如,在iPhone(不是iPad)上的视频无法在网页上内联播放,它会全屏显示。所以我创建了一个测试“无页内视频”
然后,您可以在CSS中使用它(如果测试失败,Modernizr会.no-inpagevideo
在<html>
标签中添加一个类)
.no-inpagevideo video.product-video
{
display: none;
}
这将在iPhone上隐藏视频(在这种情况下,我实际上正在做的是显示带有单击单击的替代图像来播放视频-我只是不希望显示默认的视频播放器和播放按钮)。
playsinline
因此您现在可以'playsInline' in document.createElement('video');
用作测试 github.com/Modernizr/Modernizr/issues/2077
哇,这里有很多冗长的棘手代码。请保持简单!
这是恕我直言,快速,保存,并且工作良好:
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);
iOS = /^(iPhone|iPad|iPod)/.test(navigator.platform);
而不是这样做iOS = /^(iPhone|iPad|iPod)/.test(navigator.userAgent || navigator.vendor || navigator.platform);
,我会 在我的情况下作为后备措施cuz在navigator.platform中不起作用,但是像以后那样工作时效果很好
navigator.platform
没有工作吗?那您真的在iOS上吗?检查jeka.info/test/navigator.html。userAgent
之所以提供误报,是因为无论出于何种原因,一些供应商都会伪造它来模仿Apple设备。vendor
刚刚传回Google Inc.
,Apple Computer, Inc.
或没有(在Firefox)。
这里的先前答案均不适用于所有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,因为没有Mac带有触摸屏(对kikiwora表示感谢maxTouchPoints
)。请注意,这maxTouchPoints
适用undefined
于iOS 12及以下版本,因此我们需要针对该场景的其他解决方案...
iOS 12及以下版本具有Mac OS中不存在的怪癖。奇怪的是,元素的volume
属性Audio
无法成功设置为以外的任何值1
。这是因为Apple不允许Audio
iOS设备的元素上的音量更改,但Mac OS则允许。该怪癖可以用作区分iOS设备和Mac OS设备的最终后备方法。
在我的情况下,用户代理还不够好,因为在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
}
var isiOSSafari = (navigator.userAgent.match(/like Mac OS X/i)) ? true: false;