26

我可以在 iPhone 上检测到 iOS 13,但在 iPad OS 13navigator.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 并完美运行。

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

4

6 回答 6

30

我能够通过检查navigator.maxTouchPoints以及navigator.platform. 它并不完美(如下面的评论中所讨论的),但它是迄今为止我遇到的最好的解决方案,所以我想分享一下。

const iPad = (userAgent.match(/(iPad)/) /* iOS pre 13 */ || 
  (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1) /* iPad OS 13 */);
于 2019-09-13T13:55:02.167 回答
7

TL;博士

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。上面的沙盒链接显示了输出。

于 2020-07-19T11:13:28.490 回答
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 解决方案。不要仅仅因为用户使用其他浏览器而将其锁定。您可以通知他们,但让他们选择隐藏通知并使用您的网站。

作为用户,我讨厌有人告诉我去使用另一个浏览器

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

于 2019-09-23T14:34:47.143 回答
3

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

全面披露,我是 WURFL 和 ImageEngine 背后公司的首席运营官,但我也是一名开源开发人员:)

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

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

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

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

console.log(WURFL.complete_device_name);

注意:使用付费版本,您可以获得更准确的结果(例如:Apple iPhone XS Max、、Apple iPad Pro 11)以及许多其他设备特性。

如果您不需要初始绘制的设备信息,您也可以异步运行它,这样它就不会阻塞渲染。把它贴在身体的末端并使用asyncor defer

<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/

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

于 2019-12-05T03:45:13.757 回答
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

于 2019-11-26T11:10:32.550 回答
0

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

第一个块只是嗅探旧 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;
    }
于 2019-12-13T06:46:31.813 回答