Как определить версию ОС iPad и iPad в iOS 13 и новее?

Я могу обнаружить iOS 13 на iPhone, но в 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 и отлично работает.

Может ли кто-нибудь предложить способ идентифицировать iPad, работающий на iOS 13 и выше, с помощью Javascript?

6 ответов

Мне удалось заставить обнаружение iPad работать, проверив navigator.maxTouchPoints так же как navigator.platform. Это не идеально (как обсуждается в комментариях ниже), но это лучшее решение, с которым я когда-либо сталкивался, поэтому я хотел поделиться.

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

TL;DR

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

Мы можем использовать navigator.standaloneпарам. Это нестандартно и в настоящее время используется только в iOS Safari:

Navigator.standalone

Возвращает логическое значение, указывающее, работает ли браузер в автономном режиме. Доступно только в Safari для iOS от Apple.

В сочетании с navigator.platform === "MacIntel" iPad - единственные устройства, которые определяют это свойство, поэтому typeof navigator.standalone !== "undefined" отфильтровывает Mac с Safari (с сенсорным экраном или без).

Я установил 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 показывает результат.

Все просто - нельзя. Вы можете использовать только такие хаки

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

Первое условие для "мобильного", второе для iPad, имитирующего Macintosh Safari. У меня работает надежно, но кто знает, что изменится в будущем. Если должны быть Mac с сенсорным экраном, он будет обнаруживать не только iPad в режиме рабочего стола, но и обычные Mac.

Другой способ - это обнаружение функций - вы можете, но, вероятно, не должны полагаться на поддержку функций браузера. Например, Safari на Mac не поддерживает выбор даты, а мобильная версия поддерживает.

В любом случае, я предлагаю вам попытаться не полагаться на обнаружение платформы (которое в любом случае будет нарушено в будущем) и вместо этого использовать обнаружение функций (но не для отдельных платформ) в качестве Modernizr - если вы хотите использовать средство выбора даты, вы можете проверить, есть ли это доступно, а если нет, используйте вместо этого решение HTML. Не блокируйте пользователей только потому, что они используют другой браузер. Вы можете уведомить их, но дать им возможность скрыть уведомление и в любом случае использовать ваш сайт.

Как пользователь, я ненавижу, когда кто-то говорит мне пойти и использовать другой браузер.

Просто помните - обнаружение платформы указывает на неприятный запах кода, поскольку все это взломы.

Вы можете использовать WURFL.js, который является бесплатным, если вы просто хотите знать, какое устройство используется: https://web.wurfl.io/

Полное раскрытие информации, я главный операционный директор компании, стоящей за 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), а также многие другие характеристики устройства.

Если вам не нужна информация об устройстве для начальной отрисовки, вы также можете запустить ее асинхронно, чтобы она не блокировала рендеринг. Наклейте его на конец тела и используйтеasync или 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/

Обратите внимание, что в отличие от других ответов, этот не требует постоянного обслуживания со стороны разработчика.

Я немного расширил реализацию, чтобы использовать еще несколько функций браузера по умолчанию в 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

Это немного взломано и, конечно, небезопасно в будущем, но сейчас мы используем следующее, и, похоже, это помогает.

Первый блок просто обнюхивает пользовательский агент для старых iPad, а второй блок после "ИЛИ" проверяет, является ли платформа 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;
    }
Другие вопросы по тегам