Определить, является ли устройство iOS

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

Обычно я бы предпочел вместо этого обнаружение функций, но мне нужно выяснить, является ли устройство iOS, из-за того, как они обрабатывают видео в соответствии с этим вопросом API YouTube не работает с iPad/iPhone/устройством без Flash


В iOS 13 iPad изменяются как строки агента пользователя, так и строки платформы, и кажется возможным различать iPad и MacOS, поэтому во всех приведенных ниже ответах это необходимо учитывать сейчас.

Это может быть самая короткая альтернатива, которая также охватывает iOS 13:

  function iOS () {return ['iPad Simulator', 'iPhone Simulator', 'iPod Simulator',  'iPad', 'iPhone', 'iPod'] .includes (navigator.platform)//Обнаружение iPad на iOS 13 ||  (navigator.userAgent.includes ("Mac") && "ontouchend" в документе)}  

iOS будет либо true или false

Хуже того: сниффинг пользовательского агента

Анализ пользовательского агента более опасен, и проблемы возникают часто .

На iPad iOS 13 пользовательский агент идентичен агенту на компьютере MacOS 13 , но если вы проигнорируете iPad, это может еще некоторое время работать:

  var iOS =! window.MSStream &&/iPad|iPhone|iPod/.test(navigator.userAgent); //не работает на iPad iOS 13  

! window.MSStream не должен неправильно определять IE11, см. здесь и здесь.

Примечание. И navigator.userAgent , и navigator.platform могут быть подделаны пользователем или расширение браузера.

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

Для деэскалации этого конфликта с пользователями рекомендуется определять для каждого случая именно те функции, которые необходимы вашему сайту. Затем, когда пользователь получит браузер с необходимой функцией, он уже будет работать без дополнительных изменений кода.

Наиболее распространенный способ определения версии iOS — это синтаксический анализ ее из строки User Agent. Но есть также функция обнаружение вывод *;

Мы точно знаем, что API истории был представлен в iOS4 matchMedia API в iOS5 webAudio API в iOS6 WebSpeech API в iOS7 и т. д.

Примечание. Следующий код ненадежен и выйдет из строя, если какая-либо из этих функций HTML5 устарела в новой версии iOS.. Вы были предупреждены!

  function iOSversion () {if (iOS) {// 

После iOS 13 вы должны обнаружить iOS таких устройств, поскольку iPad не будет определяться как устройства iOS старыми способами (из-за новых опций «рабочего стола», включенных по умолчанию):

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

Первое условие для iOS

Скорее хак, чем реальное решение, но у меня работает надежно

PS Как было сказано ранее, вам, вероятно, следует добавить проверку IE

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


После iOS 13 вы должны обнаруживать подобные устройства iOS, поскольку iPad не будет определяться как устройства iOS старыми способами (из-за новых опций «рабочего стола» , включено по умолчанию):

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

Первое условие для iOS

Скорее хак, чем реальное решение, но у меня работает надежно

PS Как было сказано ранее, вам, вероятно, следует добавить проверку IE

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

Это устанавливает для переменной _iOSDevice значение true или false

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


Это устанавливает переменную _iOSDevice на true или

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

Если вы используете Modernizr, вы можете добавить собственный тест для него.

Неважно, какой режим обнаружения вы решите использовать (userAgent, navigator.vendor или navigator.platform), вы всегда можете завершить его для более удобного использования позже.

 //Добавить Modernizr testModernizr.addTest ('isios', function () {return navigator.userAgent.match (/(iPad | iPhone | iPod)/g);}); //usageif (Modernizr.isios) {//это добавляет класс ios в тело Modernizr.prefixed ('ios');} else {//это добавляет класс notios в тело Modernizr.prefixed ('notios');}  


Если вы используете Modernizr, вы можете добавить для него собственный тест.

Это Независимо от того, какой режим обнаружения вы решите использовать (userAgent, navigator.vendor или navigator.platform), вы всегда можете завершить его для более удобного использования позже.

 //Add Modernizr testModernizr.addTest ('isios', function () {return navigator.userAgent.match (/(iPad | iPhone | iPod)/g);});//usageif (Modernizr.isios) {//это добавляет  ios класс в тело Modernizr.prefixed ('ios');} else {//это добавляет класс notios в тело Modernizr.prefixed ('notios');}  

Упрощенная, легко расширяемая версия.

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


Упрощенная, легко расширяемая версия.

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

Ни один из предыдущих ответов здесь не работает для всех основных браузеров во всех версиях iOS, включая iOS 13. Вот решение, которое работает для Safari, Chrome и Firefox для всех версий iOS:

  var isIOS = (function () {var iosQuirkPresent = function () {var audio = new Audio ();  audio.volume = 0,5;  вернуть audio.volume === 1; //громкость не может быть изменена с "1" на iOS 12 и ниже};  var isIOS =/iPad|iPhone|iPod/.test(navigator.userAgent);  var isAppleDevice = navigator.userAgent.includes ('Macintosh');  var isTouchScreen = navigator.maxTouchPoints> = 1; //верно для iOS 13 (и, надеюсь, позже) 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.


Ни один из предыдущих ответов здесь не работает для всех основных браузеров во всех версиях iOS, включая iOS 13. Вот решение, которое работает для Safari, Chrome и Firefox для всех версий iOS:

  var isIOS = (function () {var iosQuirkPresent = function () {var audio = new Audio (); audio.volume = 0.5; return audio.volume === 1;//volume не может быть изменен с "1" на iOS 12 и ниже}; var isIOS =/iPad|iPhone|iPod/.test(navigator.userAgent); var isAppleDevice = navigator.userAgent.includes ('Macintosh'); var isTouchScreen  = navigator.maxTouchPoints> = 1;//true для iOS 13 (и, надеюсь, в дальнейшем) 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 под управлением iOS 13 для navigator.platform установлено значение MacIntel , что означает, что вам понадобится чтобы найти другой способ обнаружения устройств iPadOS.


Вероятно, стоит ответить, что iPad под управлением iOS 13 будет иметь navigator.platform установлен на MacIntel , что означает, что вам нужно найти другой способ обнаружения устройств iPadOS.


Вики-сайт сообщества, поскольку в очереди редактирования указано, что он заполнен, а все остальные ответы в настоящее время устарели или неполны.

  const iOS_1to12 =/iPad |  iPhone | iPod/.test (navigator.platform); const iOS13_iPad = (navigator.platform === 'MacIntel' && navigator.maxTouchPoints> 1)); const iOS1to12qui  rk = функция () {var audio = new Audio (); //временный аудио объект audio.volume = 0.5; //не действует на iOS  


Вики-страницы сообщества, поскольку в очереди редактирования указано, что она заполнена, а все остальные ответы в настоящее время являются устаревшими или неполными.

  const iOS_1to12 =/iPad|iPhone|iPod/.test(navigator.platform);const iOS13_iPad = (navigator.platform === 'MacIntel' && navigator.maxTouchPoints> 1)); const  iOS1to12quirk = функция () {var audio = new Audio (); //временный аудио объект audio.volume = 0.5; //не действует на iOS  

Я написал это пару лет назад, но считаю, что это все еще работает:

  if (navigator.vendor! = null && navigator.vendor.match (/Apple Computer, Inc./) && navigator.userAgent.match (/iPhone/i) || (navigator.userAgent.match (/iPod/i  ))) {alert ("iPod или iPhone");  } иначе 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) {предупреждение ("Safari");  } else if (navigator.vendor == null || navigator.vendor! = null) {alert ("Браузер не на базе Apple");  }  


Я написал это пару лет назад, но считаю, что это все еще работает:

  if (navigator.vendor! = null && navigator.vendor.match (/Apple Computer, Inc./) && navigator.userAgent.match (/iPhone/i) || (navigator.userAgent.match (/iPod /i))) {alert ("Ipod или Iphone");  } иначе if (navigator.vendor! = null && navigator.vendor.match (/Apple Computer, Inc./) && navigator.userAgent.match (/iPad/i)) {alert ("Ipad");  } иначе 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 ("Браузер не на базе Apple");  }  

По возможности при добавлении тестов Modernizr вы должны добавить тест для функции, а не чем устройство или операционная система. Нет ничего плохого в том, чтобы добавить десять тестов, все тесты для iPhone, если это то, что нужно. Некоторые вещи просто невозможно обнаружить.

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

Например, на iPhone (не iPad) видео не может быть воспроизведено на веб-странице в режиме онлайн, оно открывается в полноэкранном режиме. Итак, я создал тестовое ‘no-inpage-video’

Затем вы можете использовать его в css (Modernizr добавляет класс .no-inpagevideo в , если тест не прошел)

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

Это скроет видео на iPhone (то, что я на самом деле делаю в этом случае, показывает альтернативное изображение с onclick для воспроизведения видео — мне просто не нужен видеоплеер по умолчанию и воспроизведение кнопку для отображения).


По возможности при добавлении тестов Modernizr вы должны добавлять тест для функции, а не для устройства или операционной системы. Нет ничего плохого в том, чтобы добавить десять тестов, все тесты для iPhone, если это то, что нужно. Некоторые вещи просто невозможно обнаружить.

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

Например, на iPhone (не iPad) видео не может быть воспроизведено на веб-странице в режиме онлайн, оно открывается в полноэкранном режиме. Итак, я создал тестовое ‘no-inpage-video’

Затем вы можете использовать его в css (Modernizr добавляет класс . no-inpagevideo в тег , если тест не прошел)

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

Это скроет видео на iPhone (то, что я на самом деле делаю в этом случае, показывает альтернативное изображение с onclick для воспроизведения видео — я просто не хочу, чтобы отображался видеоплеер и кнопка воспроизведения по умолчанию).


ОБНОВЛЕНИЕ: мой исходный ответ не распространяется на iPad в режиме рабочего стола (по умолчанию он переходит в режим рабочего стола в будущих iPadOS 13 и новее).
Это нормально для моего варианты использования, если это не для вас, используйте это обновление:

 //iPhone и iPad, включая iPadOS 13+, независимо от настроек режима рабочего стола iOSiPadOS =/^iP/.test(navigator.  платформа) || /^Mac/.test(navigator.platform) && navigator.maxTouchPoints> 4;  
  • Это должно быть безопасно, пока
    • настольные компьютеры Mac вообще не поддерживают события касания
    • или не более 4 точек касания (текущие устройства iOS поддерживают 5 точек касания)
  • Это быстро , потому что регулярное выражение ^ сначала проверяет начальную позицию строки платформы и останавливается, если нет «iP» (быстрее, чем поиск в длинной строке UA до конца)
  • Это безопаснее , чем navigator.userAgent проверьте, поскольку navigator.platform гораздо реже подделка
  • Обнаруживает симулятор iPhone/iPad

ОРИГИНАЛЬНЫЙ ОТВЕТ :
Вау, здесь много длинного хитрого кода. Будьте проще, пожалуйста!

ИМХО, это быстро, сохраняет и работает хорошо:

  iOS =/^iP/.test(navigator.platform)  ; //или, если вы предпочитаете подробный: iOS =/^(iPhone|iPad|iPod)/.test(navigator.platform);  


ОБНОВЛЕНИЕ: мой исходный ответ не касается iPad в режиме рабочего стола (по умолчанию режим рабочего стола изменяется в предстоящих iPadOS 13 и выше).
Это нормально для моих сценариев использования, если не для вас, используйте это обновление:

 //iPhone и iPad  включая iPadOS 13+ независимо от настроек режима рабочего стола iOSiPadOS =/^iP/.test(navigator.platform) || /^Mac/.test(navigator.platform) && navigator.maxTouchPoints> 4;  
  • Это должно быть безопасно, пока
    • настольные компьютеры Mac вообще не поддерживают события касания
    • или не более 4 точек касания (текущие устройства iOS поддерживают 5 точек касания)
  • Это быстро , потому что регулярное выражение ^ сначала проверяет начальную позицию строки платформы и останавливается, если нет «iP» (быстрее, чем поиск в длинной строке UA до конца)
  • Это безопаснее , чем навигатор. userAgent проверьте, так как navigator.platform гораздо реже подделка
  • Обнаруживает симулятор iPhone/iPad

ОРИГИНАЛЬНЫЙ ОТВЕТ:
Ух ты, здесь много длинного хитрого кода. Будьте проще, пожалуйста!

ИМХО, это быстро, сохраняет и работает хорошо:

  iOS =/^iP/.test(navigator.platform)  ; //или, если вы предпочитаете подробный: iOS =/^(iPhone|iPad|iPod)/.test(navigator.platform);  

Пользовательские агенты на устройствах iOS говорят в них iPhone или iPad. Я просто фильтрую по этим ключевым словам.


Пользовательские агенты на устройствах iOS говорят в них iPhone или iPad. Я просто фильтрую по этим ключевым словам.


Немного обновляю первый ответ, используя более функциональный подход.

  const isIOS = ['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod',] .indexOf (navigator.platform  )! == -1;  


Немного обновите первый ответ, используя более функциональный подход.

  const isIOS = ['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod',] .indexOf  (navigator.platform)! == -1;  

Вы также можете использовать включает

  const isApple = ['iPhone', 'iPad', 'iPod', 'iPad Simulator', 'iPhone Simulator', 'iPod  Simulator ',]. Includes (navigator.platform)  


Вы также можете использовать includes

  const isApple  = ['iPhone', 'iPad', 'iPod', 'iPad Simulator', 'iPhone Simulator', 'iPod Simulator',]. includes (navigator.platform)  

В моем случае пользовательский агент был недостаточно хорош, так как в Ipad пользовательский агент был таким же, как в Mac OS, поэтому мне пришлось сделать неприятный трюк:

  var mql = window.matchMedia ("(ориентация: альбомная)");/** * Если мы в альбомной ориентации, но высота больше ширины  */if (mql.matches && window.screen.height> window.screen.width) {//IOS} else {//Mac OS}  


В моем случае пользовательский агент был недостаточно хорош, поскольку в Ipad он был таким же, как в Mac OS, поэтому мне пришлось проделать неприятный трюк:

   var mql = окно. matchMedia ("(ориентация: альбомная)");/** * Если мы в альбомной ориентации, но высота больше ширины */if (mql.matches && window.screen.height> window.screen.width) {// IOS} else {//Mac OS}  

Чтобы определить версию iOS, нужно деструктурировать пользовательский агент с помощью кода Javascript следующим образом:

  var res = navigator.userAgent.match (/; CPU. * OS ( d_  d)/ );  если (разрешение) {var strVer = res [длина разрешения-1];  strVer = strVer.replace ("_", ".");  версия = strVer * 1;  }  


Чтобы определить версию iOS, необходимо деструктурировать пользовательский агент с помощью кода Javascript, подобного этому:

  var res = navigator.userAgent.match (/; CPU. * OS ( d_  d)/);  если (разрешение) {var strVer = res [длина разрешения-1];  strVer = strVer.replace ("_", ".");  версия = strVer * 1;  }  

var isiOSSafari = (navigator.userAgent.match (/ как Mac OS X/i))? истина: ложь;


var isiOSSafari = (navigator.userAgent.match (/как Mac OS X/ i))? истина: ложь;

Оцените статью
techsly.ru
Добавить комментарий