Javascript 检测设备是否为 iOS

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9038625/
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-08-24 08:27:25  来源:igfitidea点击:

Detect if device is iOS

javascriptiosbrowserbrowser-feature-detection

提问by SparrwHawk

I'm wondering if it's possible to detect whether a browser is running on iOS, similar to how you can feature detect with Modernizr (although this is obviously device detection rather than feature detection).

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

Normally I would favour feature detection instead, but I need to find out whether a device is iOS because of the way they handle videos as per this question YouTube API not working with iPad / iPhone / non-Flash device

通常我更喜欢功能检测,但我需要找出设备是否是 iOS,因为它们按照这个问题处理视频的方式YouTube API 不适用于 iPad / iPhone / 非 Flash 设备

回答by Pierre

Detecting iOS

检测iOS

I am not a fan of User Agent sniffing, but here is how you would do it:

我不是用户代理嗅探的粉丝,但您可以这样做:

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

Another way is relying on navigator.platform:

另一种方法是依靠navigator.platform

var iOS = navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);

iOSwill be either trueor false

iOS将是truefalse

Why not MSStream

为什么不是 MSStream

Microsoft injected the word iPhonein IE11's userAgentin order to try and fool Gmail somehow. Therefore we need to exclude it. More info about this hereand here.

微软在 IE11 中注入了iPhone一词,userAgent以试图以某种方式欺骗 Gmail。因此我们需要排除它。更多关于这里这里的信息

Below is IE11's updated userAgent(Internet Explorer for Windows Phone 8.1 Update):

以下是 IE11 的更新userAgent(Windows Phone 8.1 更新的 Internet Explorer):

Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 930) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537

Mozilla/5.0(移动;Windows Phone 8.1;Android 4.0;ARM;Trident/7.0;Touch;rv:11.0;IEMobile/11.0;NOKIA;Lumia 930)如 iPhone OS 7_0_3 Mac OS X AppleWebKit/537(KHTML,如 Gecko)移动 Safari/537



Easily add more devices, without using Regular Expressions:

轻松添加更多设备,无需使用正则表达式:

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()will be either trueor false

iOS()将是truefalse

Note:Both navigator.userAgentand navigator.platformcan be faked by the user or a browser extension.

注意:无论navigator.userAgent并且navigator.platform可以由用户或浏览器扩展伪造。



Detecting iOS version

检测iOS版本

The most common way of detecting the iOS version is by parsing it from the User Agent string. But there is also feature detectioninference*;

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

We know for a fact that history APIwas introduced in iOS4- matchMedia APIin iOS5- webAudio APIin iOS6- WebSpeech APIin iOS7and so on..

我们知道history APIiOS4-matchMedia APIiOS5-webAudio APIiOS6-WebSpeech APIiOS7等中引入的事实..

Note:The following code is not reliable and will break if any of these HTML5 features is deprecated in a newer iOS version. You have been warned!

注意:以下代码不可靠,如果这些 HTML5 功能在较新的 iOS 版本中被弃用,则会中断。你被警告了!

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';
}

回答by kikiwora

After iOS 13 you should detect iOS devices like this, since iPad will not be detected as iOS devices by old ways (due to new "desktop" options, enabled by default):

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

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

The first condition for iOS < 13 or iPhone or iPad with disabled Desktop mode, the second condition for iPadOS 13 in the default configuration, since it position itself like Macintosh Intel, but actually is the only Macintosh with multi-touch.

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

Rather a hack than a real solution, but work reliably for me

与其说是一个真正的解决方案,不如说是一个黑客,但对我来说可靠地工作

P.S.As being said earlier, you probably should add IE checkup

PS如前所述,您可能应该添加 IE 检查

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

回答by Vitim.us

This sets the variable _iOSDeviceto trueor false

这将变量设置_iOSDevicetruefalse

_iOSDevice = !!navigator.platform.match(/iPhone|iPod|iPad/);

回答by ThiagoPXP

If you are using Modernizr, you can add a custom test for it.

如果您使用的是Modernizr,则可以为其添加自定义测试。

It doesn't matter which detection mode you decide to use (userAgent, navigator.vendor or navigator.platform), you can always wrap it up for a easier use later.

无论您决定使用哪种检测模式(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');
}

回答by sgt9dg8s90

There is this custom Modernizr tests: https://gist.github.com/855078

有这个自定义 Modernizr 测试:https: //gist.github.com/855078

回答by Kory Nunn

A simplified, easy to extend version.

一个简化的、易于扩展的版本。

var iOS = ['iPad', 'iPhone', 'iPod'].indexOf(navigator.platform) >= 0;

回答by Justin Searls

It's probably worth answering that iPads running iOS 13 will have navigator.platformset to MacIntel, which means you'll need to find another way to detect iPadOS devices.

可能值得回答的是,运行 iOS 13 的 iPad 将navigator.platform设置为MacIntel,这意味着您需要找到另一种方法来检测 iPadOS 设备。

回答by Michael Benin

I wrote this a couple years ago but i believe it still works:

我几年前写过这个,但我相信它仍然有效:

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");

    }

回答by Simon_Weaver

Wherever possible when adding Modernizr tests you should add a test for a feature, rather than a device or operating system. There's nothing wrong with adding ten tests all testing for iPhone if that's what it takes. Some things just can't be feature detected.

在添加 Modernizr 测试时,只要有可能,您应该为功能而不是设备或操作系统添加测试。如果需要的话,为 iPhone 添加十个测试并没有错。有些东西就是不能被特征检测到。

    Modernizr.addTest('inpagevideo', function ()
    {
        return navigator.userAgent.match(/(iPhone|iPod)/g) ? false : true;
    });

For instance on the iPhone (not the iPad) video cannot be played inline on a webpage, it opens up full screen. So I created a test 'no-inpage-video'

例如,在 iPhone(不是 iPad)上,视频不能在网页上内联播放,它会全屏播放。所以我创建了一个测试“无页内视频”

You can then use this in css (Modernizr adds a class .no-inpagevideoto the <html>tag if the test fails)

然后你可以在 css 中使用它(如果测试失败,Modernizr 会.no-inpagevideo<html>标签中添加一个类)

.no-inpagevideo video.product-video 
{
     display: none;
}

This will hide the video on iPhone (what I'm actually doing in this case is showing an alternative image with an onclick to play the video - I just don't want the default video player and play button to show).

这将隐藏 iPhone 上的视频(在这种情况下我实际上正在做的是显示一个带有 onclick 的替代图像来播放视频 - 我只是不希望显示默认的视频播放器和播放按钮)。

回答by j.j.

Wow, a lot of longish tricky code here. Keep it simple, please!

哇,这里有很多冗长的棘手代码。请保持简单!

This one is IMHO fast, save, and working well:

恕我直言,这是一种快速、保存且运行良好的方法:

 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);
  • It's fast because the regexp checks the ^starting position of the platform string first and stops if there is no "iP" (faster than searching the long UA string until the end anyway)
  • It's safer than UA check (assuming navigator.platform is less likely faked)
  • Detects iPhone / iPad Simulator
  • 它很快,因为正则表达式首先检查平台字符串的^s起始位置,如果没有“iP”则停止(无论如何比搜索长 UA 字符串直到结束要快)
  • 它比 UA 检查更安全(假设 navigator.platform 不太可能伪造)
  • 检测 iPhone / iPad 模拟器



更新:这不包括 iPad desktop mode桌面模式(因此默认为 iPadOS 13)。


这对我的用例很好,如果不适合你,请参阅 Justin 和 kikiwora 的答案。