【问题标题】:How to detect iPad and iPad OS version in iOS 13 and Up?如何在 iOS 13 及更高版本中检测 iPad 和 iPad OS 版本?
【发布时间】:2020-01-06 00:33:14
【问题描述】:

我可以在 iPhone 上检测到 iOS 13,但在 iPad OS 13 中 navigator.platform 来自 MacIntel。因此无法使用下面的代码识别 iPad,但它可以在 iPhone 上完美运行。

    if (/iP(hone|od|ad)/.test(navigator.platform)) {
            var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
            var version = [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)];
            return version;
    }

当我们在 iPad 上使用浏览器请求移动网站时,navigator.platform 返回为 iPad 并完美运行。

谁能建议一种方法来使用 Javascript 识别 在 iOS 13 及更高版本上运行的 iPad

【问题讨论】:

标签: javascript ios ipad ios13 ipados13


【解决方案1】:

我确实稍微扩展了实现,以便在 iPad OS 和 Mac OS Catalina 上使用更多默认浏览器功能。 根据我在各种 iPad 和所有后期 iOS 设备上的测试,这运行良好。

var isIPadOs = window.AuthenticatorAssertionResponse === undefined
        && window.AuthenticatorAttestationResponse === undefined
        && window.AuthenticatorResponse === undefined
        && window.Credential === undefined
        && window.CredentialsContainer === undefined
        && window.DeviceMotionEvent !== undefined
        && window.DeviceOrientationEvent !== undefined
        && navigator.maxTouchPoints === 5
        && navigator.plugins.length === 0
        && navigator.platform !== "iPhone";

要点:https://gist.github.com/braandl/f7965f62a5fecc379476d2c055838e36

【讨论】:

  • 感谢您的努力!但是下一个 iPadOS 或 iPad 设备不能改变这种情况吗?
  • 是的,绝对。所有这些“指纹”方法最终都需要更新......虽然由于我对苹果浏览器更新政策的经验,这应该没问题......
  • @braandl 谢谢! window.CredentialsContainer 有一个错字!
【解决方案2】:

TL;DR

const iPad = !!(navigator.userAgent.match(/(iPad)/)
  || (navigator.platform === "MacIntel" && typeof navigator.standalone !== "undefined"))

我们可以使用navigator.standalone 参数。它是非标准的,目前仅在 iOS Safari 上使用:

Navigator.standalone

返回一个布尔值,指示浏览器是否在独立模式下运行。仅适用于 Apple 的 iOS Safari。

当与navigator.platform === "MacIntel" 结合使用时,iPad 是唯一定义此属性的设备,因此typeof navigator.standalone !== "undefined" 会过滤掉运行 Safari(无论是否触摸屏)的 Mac。

我设置了一个 CodeSandbox 并在 Browserstack 上手动测试,似乎按预期工作:https://bc89h.csb.app/

版本检测(仅限 iOS)

我没有对此进行过广泛的测试,但应该给其他人一个很好的起点:

const version = navigator.userAgent.match(/Version\/(\d+)\.(\d+)\.?(\d+)?/);
const major = version && version[1] ? version[1] : "";
const minor = version && version[2] ? version[2] : "";
const patch = version && version[3] ? version[3] : "";

以上内容将版本分解为主要、次要和补丁元素。这似乎适用于我对其进行快速测试的 iOS 12 和 13。上面的 SandBox 链接显示了输出。

【讨论】:

  • 在 TL;DR 中,您可以使用不带括号的 /iPad/
【解决方案3】:

这很简单——你不能。你只能使用这样的技巧

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

“移动”的第一个条件,模仿 Macintosh Safari 的 iPad 的第二个条件。 它对我来说很可靠,但谁知道将来会发生什么变化。 如果有带触摸屏的 Mac,这不仅会检测处于桌面模式的 iPad,还会检测到普通 Mac。

另一种方法是功能检测 - 您可以,但可能不应该依赖浏览器功能支持。例如,Mac 上的 Safari 不支持日期选择器,但移动端支持。

无论如何,我建议您尽量不要依赖平台检测(无论如何将来都会被破坏)并使用功能检测(但不是针对不同平台)作为 Modernizr - 如果您想使用日期选择器,您可以检查如果可用,如果不可用,请改用 HTML 解决方案。不要仅仅因为用户使用其他浏览器而将其锁定。您可以通知他们,但让他们选择隐藏通知并使用您的网站。

作为用户,我讨厌有人告诉我去使用其他浏览器

请记住 - 平台检测表明代码味道不好,因为所有这些都是 hack。

【讨论】:

    【解决方案4】:

    这有点骇人听闻,而且未来肯定不是很安全,但现在我们正在使用以下方法,它似乎可以解决问题。

    第一个块只是嗅探旧 iPad 的用户代理,'OR' 之后的第二个块是检查平台是否为 Macintosh 并具有接触点。在撰写本文时,还没有适用于 Mac 的官方触摸屏,因此在一段时间内应该是相当安全的。

    if ((/\b(iPad)\b/.test(navigator.userAgent)
        && /WebKit/.test(navigator.userAgent)
        && !window.MSStream)
        || (navigator.platform === 'MacIntel'
        && navigator.maxTouchPoints
        && navigator.maxTouchPoints === 5)
      ) {
            return true;
        }
    

    【讨论】:

      【解决方案5】:

      你可以使用 WURFL.js,如果你只是想知道正在使用什么设备,它是免费的:https://web.wurfl.io/#wurfl-js

      完全披露,我是 WURFL 和 ImageEngine 背后公司的首席运营官,但我也是 an open-source developer :)

      WURFL.js 可以告诉您正在使用什么操作系统以及它是 iPhone 还是 iPad。

      要使用它,只需将其添加到页面头部:

      <script type="text/javascript" src="//wurfl.io/wurfl.js"></script>
      

      然后就可以在javascript中使用设备信息了:

      console.log(WURFL.complete_device_name);
      

      注意:使用paid version,您可以获得更准确的结果(例如:Apple iPhone XS MaxApple iPad Pro 11)以及许多其他设备特征。

      如果您不需要设备信息来进行初始绘制,您也可以异步运行它,这样它就不会阻塞渲染。贴在body尾部,使用asyncdefer

      <script type="text/javascript">
      window.addEventListener('WurflJSDetectionComplete', () => {
         console.log(`Device: ${WURFL.complete_device_name}`);
      });
      </script>
      <script type="text/javascript" src="//wurfl.io/wurfl.js" async></script>
      

      当您使用它时,不妨使用此改进的设备信息来增强 Google Analytics:https://www.scientiamobile.com/wurfljs-google-analytics-iphone/

      请注意,与其他答案不同,此答案不需要开发人员进行持续维护。

      【讨论】:

      • 在 iPad 上,如果我在 safari 设置中取消选中请求桌面站点,它只会显示平板电脑,所有用户可能都不会这样做。默认情况下它显示桌面。
      • 是的,感谢您的澄清。 Apple 在去年推出了这一功能,不幸的是没有已知的解决方法,尤其是在如此强调防止指纹识别的情况下。
      【解决方案6】:

      我能够通过检查 navigator.maxTouchPointsnavigator.platform 来检测 iPad。它并不完美(如下面的 cmets 所述),但它是迄今为止我遇到的最佳解决方案,所以我想分享一下。

      const iPad = (userAgent.match(/(iPad)/) /* iOS pre 13 */ || 
        (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1) /* iPad OS 13 */);
      

      【讨论】:

      • 如果用户有触摸屏显示器,这不会返回 true 吗?
      • @Kris 我的意图是仅在运行 Safari(即仅 iOS 设备)的触摸屏显示器时才返回 true,但是……我没有考虑到 Chrome(和可能是其他人)在他们的用户代理字符串中有“Safari”。 ? 我仍然认为我在正确的轨道上......只是需要更多的迭代
      • @Kris 我已将其更新为使用navigator.platform,我认为它至少可以用于我的应用程序的目的。没有触摸屏 Mac(还没有 ?)所以任何触摸屏 MacIntel 平台都应该是 iPadOS 13+?我猜他们可能有第三方触摸屏显示器,但我不确定 MacOS 会如何回应? ?我会很高兴使用另一种方法,但这是迄今为止我见过的唯一一种方法。
      • 添加 window.devicePixelRatio 检测有助于区分 iPad 和 iPhone。在较新的 iPhone 上 window.devicePixelRatio == 3,iPad 所有 window.devicePixelRatio == 2。51degrees.com/blog/device-detection-for-apple-iphone-and-ipad
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 2016-03-30
      • 2010-11-22
      • 2014-07-05
      • 2021-12-09
      • 1970-01-01
      相关资源
      最近更新 更多