Обнаружение мобильного браузера

889

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

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

Я просматривал этот сайт , но, к сожалению, сценарий настолько загадочный, что я понятия не имею, как использовать его для своих целей, а именно для создания функции, возвращающей true / false.

пр
источник
6
Связанный: stackoverflow.com/questions/3514784/… .
Фредерик Хамиди
2
Попробуйте прочитать это. stackoverflow.com/questions/743129/…
KyelJmD
5
@ Thrustmaster: Это действительно не так. Обслуживание разных JS для разных браузеров означает, что вы должны добавить Vary: User-Agentк своему ответу, в противном случае кэширующие прокси сохранят одну версию и отправят ее в другой тип браузера. Но Vary: User-Agentделает ответ не кэшируемым в IE.
Бобинц
17
@ave: Что вы пытаетесь сделать, обнаружив «мобильный» браузер? Различие весьма спорно в современном мире планшетов и гибридных вычислительных устройств. Вы хотите обнаружить маленькие экраны и представить другой интерфейс в этом случае? Вы ищете для обнаружения подключения с низкой пропускной способностью? Вы ищете для обнаружения сенсорных интерфейсов?
Бобинц
2
Поэтому я обновил свой ответ, чтобы использовать метод javascript detemobilebrowsers.com, но возвращаю логическое значение, если это кому-то все еще нужно. ( так, на всякий случай ). Удачного обнаружения :)
Михаил Запорожец

Ответы:

1318

Используя Regex (от detectmobilebrowsers.com ):

Вот функция, которая использует безумно длинный и всеобъемлющий регулярное выражение, которое возвращает значение trueили в falseзависимости от того, просматривает ли пользователь мобильный телефон или нет.

window.mobileCheck = function() {
  let check = false;
  (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
  return check;
};

Для тех, кто хочет включить таблетки в этот тест (хотя, возможно, не стоит), вы можете использовать следующую функцию:

window.mobileAndTabletCheck = function() {
  let check = false;
  (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
  return check;
};

Оригинальный ответ

Вы можете сделать это, просто пропустив список устройств и проверив, useragentсовпадает ли что- нибудь вроде этого:

  function detectMob() {
    const toMatch = [
        /Android/i,
        /webOS/i,
        /iPhone/i,
        /iPad/i,
        /iPod/i,
        /BlackBerry/i,
        /Windows Phone/i
    ];

    return toMatch.some((toMatchItem) => {
        return navigator.userAgent.match(toMatchItem);
    });
}

Однако, поскольку вы считаете, что этот метод ненадежен, можно предположить, что любое устройство с разрешением 800x600 или менее было также мобильным устройством, что еще больше сужает вашу цель (хотя в наши дни многие мобильные устройства имеют гораздо большие разрешения, чем эта)

т.е.

  function detectMob() {
    return ( ( window.innerWidth <= 800 ) && ( window.innerHeight <= 600 ) );
  }

Ссылка:

Михаил Запорожец
источник
25
Привет, я только что посетил ссылку detemobilebrowsers.com на своем iPad 3, iOS 6.1.2, и там написано "Мобильный браузер не обнаружен"
Ричард Лавджой
49
@RichardLovejoy при создании сайтов, ipad обычно не считается мобильным.
Михаил Запорожец
42
С о странице: Android таблетки, ы, Kindle Пожары и PlayBooks не определяются конструкцией. Чтобы добавить поддержку для планшетов, добавьте |android|ipad|playbook|silkпервое регулярное выражение.
Гра Дабл
13
Google TV тоже Android. Что определяют мобильный? Размер экрана ? Сенсорный? DeviceOrientation? Когда я проектирую, это больше вопрос мыши или нет, большой бутон или маленькие ссылки. Итак, сейчас я бегу с «if (Modernizr.touch)» :)
molokoloco
31
Боже, вся эта идея пользовательских агентов ужасна и действительно должна остановиться. Нам действительно нужно прекратить позволять клиентам бороться с течением и просто придерживаться медиа-запросов. Если они хотят выполнять перенаправления в зависимости от масштаба для определенных страниц, просто проверьте диапазон определенного медиазапроса с
marksyzm,
324

Как насчет:

if (typeof window.orientation !== 'undefined') { ... }

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

РЕДАКТИРОВАТЬ: Как указал @Gajus, это решение устарело и не должно использоваться ( https://developer.mozilla.org/en-US/docs/Web/API/Window/orientation )

Йоав Барни
источник
14
это на самом деле супер уникальный и удивительный, вы не возражаете, если я добавлю это в свой ответ?
Михаил Запорожец
77
Это, вероятно, не будет работать долго. 1) Планшеты могут иметь приличный размер экрана, вы хотите, чтобы они отображали веб-сайт с полным рабочим столом, но у них будет это свойство. 2) Windows 8 уже здесь, а вместе с ней куча ноутбуков с сенсорным экраном и вращающимися экранами.
Дэйв Хильдич
10
Что касается вашего первого замечания о планшетах с приличными размерами экрана - я думаю, вы могли бы привести те же аргументы и ко всем остальным решениям (планшет с большим экраном, который отслеживается как маленький экран). В любом случае, идея заключается в том, чтобы искать свойство, которое используется совместно с небольшими устройствами, вместо того, чтобы хранить длинный код обслуживания и добавлять регулярные выражения для каждого нового устройства / модели / версии. Я думаю, что обнаружение устройств уходит в прошлое, и сегодня мы должны сосредоточиться на обнаружении функций. снова я буду рад здесь о более подходящей собственности в этом отношении ...
yoav barnea
2
Люблю это и работает отлично, спасибо. Для моего решения я был просто после простого.
Bojangles
40
window.orientationявляется устаревшим свойством ( developer.mozilla.org/en-US/docs/Web/API/Window/orientation , compat.spec.whatwg.org/#dom-window-orientation ), которое некоторые мобильные браузеры предпочитают поддерживать по неизвестным причинам , Те же браузеры реализуют window.screen.orientation(что определено и в настольных браузерах). Я могу только предположить, что window.orientationон оставлен там по старым причинам и поэтому не должен использоваться в новых приложениях.
Gajus
115
var isMobile = {
    Android: function() {
        return navigator.userAgent.match(/Android/i);
    },
    BlackBerry: function() {
        return navigator.userAgent.match(/BlackBerry/i);
    },
    iOS: function() {
        return navigator.userAgent.match(/iPhone|iPad|iPod/i);
    },
    Opera: function() {
        return navigator.userAgent.match(/Opera Mini/i);
    },
    Windows: function() {
        return navigator.userAgent.match(/IEMobile/i) || navigator.userAgent.match(/WPDesktop/i);
    },
    any: function() {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
};

Как пользоваться

if( isMobile.any() ) alert('Mobile');

Чтобы проверить, находится ли пользователь на определенном мобильном устройстве:

if( isMobile.iOS() ) alert('iOS');

Ссылка: http://www.abeautifulsite.net/blog/2011/11/detecting-mobile-devices-with-javascript

Расширенная версия на github: https://github.com/smali-kazmi/detect-mobile-browser

Мудасер Али
источник
Почему бы не сделать any()for ... в цикле isMobileчленов ORed ?
SomeShinyObject
@ChristopherW я создал его плагин и модифицировал код, как вы советовали
Mudaser Ali
2
Может быть, переместить iOS впереди BlackBerry (), чтобы сначала поставить наиболее распространенные случаи и позволить раннему спасению сэкономить некоторую дополнительную обработку?
Rob_vH
2
@Rob_vH Я поместил этот код в github ( github.com/smali-kazmi/detect-mobile-browser ) с некоторыми дополнительными функциями; Вы также можете присылать свои предложения
Мудасер Али
1
@AkarshSatija Влияет ли падение производительности этих 5 проверок регулярных выражений на какие-либо приложения? Я был бы очень удивлен, если бы это сделал. Преждевременная оптимизация может быть пустой тратой времени ...
trusktr
68

Вот простое решение из источника рогатки Facebook

var isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
if (isMobile) {
  /* your code here */
}
Santhosh
источник
Ницца. Очень полезно в определенных ситуациях
Чак Ле Батт
Полезно в случае обнаружения устройства, на котором может быть установлено мобильное приложение. Вы не заботитесь о браузере, по сути. Просто устройство / ОС.
Чарли
31

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

var touchDevice = ('ontouchstart' in document.documentElement);

Изменить . Для одновременной поддержки настольных компьютеров с сенсорным экраном и мобильных телефонов вы можете использовать следующее:

var touchDevice = (navigator.maxTouchPoints || 'ontouchstart' in document.documentElement);
Tigger
источник
9
Что делать, если монитор настольного компьютера поддерживает сенсорный экран?
Антон Кузьмин
@HappyCoder Я считаю, что операционная система должна сообщать браузеру, когда сенсорный экран на рабочем столе активен. Так что да, эта проверка все еще должна быть действительной.
Tigger
(+1), однако, мой рабочий стол теперь имеет сенсорный экран, и он не всегда соответствует touchstart|end|etc.
Коди
1
Загрузчик datepicker использует следующее: if (window.navigator.msMaxTouchPoints || 'ontouchstart' в документе) {this.input.blur (); }
JT Тейлор
1
@JTTaylor Похоже, что Microsoft рекомендует navigator.maxTouchPoints (без msпрефикса). Есть также статья MDN, чтобы проверить.
Тигр
20

Как уже отмечалось, полагаться на движущуюся цель данных пользовательского агента проблематично. То же самое можно сказать и о размере экрана.

Мой подход заимствован из техники CSS, чтобы определить, является ли интерфейс сенсорным:

Использование только JavaScript (поддержка со всеми современными браузерами), медиа запросов матч можно легко сделать вывод , является ли устройство мобильным .

function isMobile() {
    var match = window.matchMedia || window.msMatchMedia;
    if(match) {
        var mq = match("(pointer:coarse)");
        return mq.matches;
    }
    return false;
}
gsxrboy73
источник
6
А как насчет ноутбуков с сенсорным дисплеем?
Максим
6
Я бы проверил! MatchMedia ("(any-pointer: fine)"). Соответствует самому себе. («Нет подключенной мыши», а не «есть сенсорный экран».
Sora2455
Это работает, в то время как мой последний сценарий обманут люди, использующие функцию масштабирования браузера (например, парень, с которым я разговаривал на 13 "экране с 4K, который упал до 1080p и все еще должен был использовать масштабирование). Работал на моем iPhone (Safari / Устройства Firefox) и Android (Waterfox / Chrome / «Браузер»). Определенно, намного надежнее, чем все ответы с более высоким
Джон
не обнаруживает FireFox fennec на Android, для которого я добавил Navigator.userAgent.toLowerCase (). indexOf ('fennec')> -1 (возможно, не лучшее дополнение ..)
StayCool
2
Дополнительно вы можете протестировать свойство hover: для смартфонов и сенсорных экранов @media (hover: нет) и (указатель: грубый)
Batailley
16

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

Тем не менее, если нужно использовать пользовательский агент в качестве средства обнаружения мобильного устройства, они предлагают:

Таким образом, мы рекомендуем искать строку «Mobi» в любом месте в User Agent, чтобы обнаружить мобильное устройство.

Следовательно, этого однострочного будет достаточно:

const isMobileDevice = window.navigator.userAgent.toLowerCase().includes("mobi");

[ОБНОВИТЬ]:

Как подсказывает @ zenw0lf в комментариях, лучше использовать регулярное выражение:

const isMobileDevice = /Mobi/i.test(window.navigator.userAgent)

TheDarkIn1978
источник
.includesне поддерживается IE-11
Паша Олейник,
1
@PashaOleynik полифилл может это исправить
Максим
Планшет Nexus 7 с Android не имеет Mobileв строке агента пользователя
Алексей Сороколетов
@AlexSorokoletov Также для статьи MDNIf the device is large enough that it's not marked with “Mobi”, you should serve your desktop site (which, as a best practice, should support touch input anyway, as more desktop machines are appearing with touchscreens).
TheDarkIn1978
1
Я думаю, что это будет работать в любом месте без полифилов: const isMobile = /Mobi/.test(window.navigator.userAgent)
zenw0lf
14

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

Вариант 1: браузер нюхает

!function(a){var b=/iPhone/i,c=/iPod/i,d=/iPad/i,e=/(?=.*\bAndroid\b)(?=.*\bMobile\b)/i,f=/Android/i,g=/(?=.*\bAndroid\b)(?=.*\bSD4930UR\b)/i,h=/(?=.*\bAndroid\b)(?=.*\b(?:KFOT|KFTT|KFJWI|KFJWA|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|KFARWI|KFASWI|KFSAWI|KFSAWA)\b)/i,i=/IEMobile/i,j=/(?=.*\bWindows\b)(?=.*\bARM\b)/i,k=/BlackBerry/i,l=/BB10/i,m=/Opera Mini/i,n=/(CriOS|Chrome)(?=.*\bMobile\b)/i,o=/(?=.*\bFirefox\b)(?=.*\bMobile\b)/i,p=new RegExp("(?:Nexus 7|BNTV250|Kindle Fire|Silk|GT-P1000)","i"),q=function(a,b){return a.test(b)},r=function(a){var r=a||navigator.userAgent,s=r.split("[FBAN");return"undefined"!=typeof s[1]&&(r=s[0]),s=r.split("Twitter"),"undefined"!=typeof s[1]&&(r=s[0]),this.apple={phone:q(b,r),ipod:q(c,r),tablet:!q(b,r)&&q(d,r),device:q(b,r)||q(c,r)||q(d,r)},this.amazon={phone:q(g,r),tablet:!q(g,r)&&q(h,r),device:q(g,r)||q(h,r)},this.android={phone:q(g,r)||q(e,r),tablet:!q(g,r)&&!q(e,r)&&(q(h,r)||q(f,r)),device:q(g,r)||q(h,r)||q(e,r)||q(f,r)},this.windows={phone:q(i,r),tablet:q(j,r),device:q(i,r)||q(j,r)},this.other={blackberry:q(k,r),blackberry10:q(l,r),opera:q(m,r),firefox:q(o,r),chrome:q(n,r),device:q(k,r)||q(l,r)||q(m,r)||q(o,r)||q(n,r)},this.seven_inch=q(p,r),this.any=this.apple.device||this.android.device||this.windows.device||this.other.device||this.seven_inch,this.phone=this.apple.phone||this.android.phone||this.windows.phone,this.tablet=this.apple.tablet||this.android.tablet||this.windows.tablet,"undefined"==typeof window?this:void 0},s=function(){var a=new r;return a.Class=r,a};"undefined"!=typeof module&&module.exports&&"undefined"==typeof window?module.exports=r:"undefined"!=typeof module&&module.exports&&"undefined"!=typeof window?module.exports=s():"function"==typeof define&&define.amd?define("isMobile",[],a.isMobile=s()):a.isMobile=s()}(this);

alert(isMobile.any ? 'Mobile' : 'Not mobile');

Этот конкретный код анализа браузера - это библиотека isMobile .


Вариант 2: оконная ориентация

Проверить, если window.orientationопределено:

var isMobile = window.orientation > -1;
alert(isMobile ? 'Mobile' : 'Not mobile');


Запись

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

var hasTouchscreen = 'ontouchstart' in window;
alert(hasTouchscreen ? 'has touchscreen' : 'doesn\'t have touchscreen');

Джон Слегерс
источник
Ориентационный подход действительно хорош! ))
Максим
1
Мне нравится ваше window.orientationрешение, но в документах говорится, что оно устарело! developer.mozilla.org/en-US/docs/Web/API/Window/orientation
skwidbreth
3
Ориентационный подход НЕ хорош, потому что Windows 8 и выше может изменить ориентацию.
Heitor
Windows 8 и новее ориентированы на добавление поддержки мобильных устройств, а также гибридов (ноутбуков, которые могут преобразовываться в большие планшеты), поэтому ориентация не срабатывает как метод обнаружения, даже если moz не называет его устаревшим.
Джефф Клэйтон
Это из Win 7 с установленным графическим программным обеспечением может изменить ориентацию, но задайте себе вопрос, кто может на настольном компьютере / ноутбуке использовать другую ориентацию экрана, как книжная, а не альбомная, и использовать i даже более 1 минуты. Никто !!! Изменение ориентации на рабочем столе означает, что вы начнете читать символы на экране снизу вверх.
GirlCode
11

Вот решение userAgent, которое более эффективно, чем соответствие ...

function _isMobile(){
    // if we want a more complete list use this: http://detectmobilebrowsers.com/
    // str.test() is more efficent than str.match()
    // remember str.test is case sensitive
    var isMobile = (/iphone|ipod|android|ie|blackberry|fennec/).test
         (navigator.userAgent.toLowerCase());
    return isMobile;
}
JeffJak
источник
7
метод теста не чувствителен к регистру, но ваше регулярное выражение Вы можете просто /iphone|etc/i.test(navigator.userAgent)
отметить
11

Чтобы добавить дополнительный уровень контроля, я использую хранилище HTML5, чтобы определить, использует ли оно мобильное хранилище или хранилище на рабочем столе. Если браузер не поддерживает хранилище, у меня есть массив имен мобильных браузеров, и я сравниваю пользовательский агент с браузерами в массиве.

Это довольно просто. Вот функция:

// Used to detect whether the users browser is an mobile browser
function isMobile() {
    ///<summary>Detecting whether the browser is a mobile browser or desktop browser</summary>
    ///<returns>A boolean value indicating whether the browser is a mobile browser or not</returns>

    if (sessionStorage.desktop) // desktop storage 
        return false;
    else if (localStorage.mobile) // mobile storage
        return true;

    // alternative
    var mobile = ['iphone','ipad','android','blackberry','nokia','opera mini','windows mobile','windows phone','iemobile']; 
    for (var i in mobile) if (navigator.userAgent.toLowerCase().indexOf(mobile[i].toLowerCase()) > 0) return true;

    // nothing found.. assume desktop
    return false;
}
Расмус Сёборг
источник
3
Я еще не тестировал на мобильных устройствах, но sessionStorage.desktopне существует ни в Safari, ни в Chrome, ни в Firefox (все новейшие версии на момент публикации). Тем не менее, вы получаете право голоса, поскольку ваше решение идет в лучшем направлении, чем другие. Но не забудьте использовать var mobile =вместо mobile =.
shuckster
3
Также хорошая идея не использовать indexOf с более старыми браузерами, которые не поддерживают этот метод, или использовать полифилл. Нет необходимости использовать toLowerCase для списка значений в нижнем регистре, и в этом нет необходимости, если вы используете /ipad|iphone|etc/i.test(navigator.userAgent) вместо медленного цикла, который у вас там есть.
Джеффри Гилберт
10

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

zadubz
источник
18
Вы ответили на другой вопрос, кроме того, что было задано. Вместо того, чтобы «как я могу обнаружить мобильный телефон?», Вы ответили «как я могу обнаружить определенные функции?». Не все устройства обнаружения предназначены для обнаружения функций. Что если бы мы искали статистику об устройствах? Тогда нет, «обнаружение признаков» не «намного лучше, чем [выяснение устройства]».
Джонатан Аллард
1
Это не ответ, но он заслуживает большего, чем просто комментарий. Вопрос в том, почему вы хотите обнаружить браузер, и тогда вы, вероятно, захотите узнать его только из-за (отсутствия) касания. Отзывчивого веб-дизайна достаточно в большинстве, если не во всех случаях.
дважды
8

Как насчет этого?

if(
    (screen.width <= 640) || 
    (window.matchMedia && 
     window.matchMedia('only screen and (max-width: 640px)').matches
    )
  ){
   // Do the mobile thing
}
stujo
источник
Почему бы просто не использовать screen.widthвместо этого? Мне кажется, это надежнее, чем window.matchMedia.
Джон Слегерс
Хороший вопрос Джон, я не могу точно вспомнить, о чем я думал в то время, кажется маловероятным (глядя на это сейчас), что второе предложение вернет true, если первое будет false. Должно быть, была какая-то причина, по которой я добавил это.
Stujo
Большинству порядочных программистов стыдно, когда они видят код, написанный самим годом ранее. Те, кто не только не вырос как программисты ;-)
Джон Слегерс
4
Разрешение окна не имеет никакого отношения к тому, находится ли браузер на мобильном устройстве или нет. Например, многие настольные браузеры работают в не полноэкранных окнах. Если вы представите пользовательскому интерфейсу, предназначенному для портативных экранов, в этих браузерах, их пользователи будут разочарованы.
ɈsәɹoɈ
1
@JohnSlegers - мне в основном стыдно погуглить вопрос и найти свой ответ на stackoverflow. снова и снова. Я сам нахожусь в постоянном переполнении стека
vsync
7

Как только элемент получает фокус, вы сразу же стираете его. Bootstrap-datepicker, который является очень популярным и хорошо поддерживаемым компонентом с почти 10000 звезд в GitHub, использует этот подход:

if (window.navigator.maxTouchPoints || 'ontouchstart' in document) {
    this.input.blur();
}

https://github.com/uxsolutions/bootstrap-datepicker

Спасибо Тигру за помощь.

Дж. Т. Тейлор
источник
7

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

Простой код JavaScript:

function isMobile() {
   try{ document.createEvent("TouchEvent"); return true; }
   catch(e){ return false; }
}

if (isMobile()) {
   # do whatever you wanna do!
}

Это сработало для меня очень хорошо, но могут быть проблемы с ноутбуками, оснащенными сенсорным дисплеем.

Я не уверен, что ноутбук с сенсорным экраном будет обнаружен как мобильное устройство, потому что я еще не тестировал его.

Нео Морина
источник
5
Ноутбуки с сенсорным экраном будут обнаружены как мобильные устройства. А также сенсорные мониторы для настольных компьютеров. Верьте или нет, вы также столкнетесь с проблемой, если вы используете устройство с сенсорным экраном для RDP на другое устройство, которое не имеет сенсорного экрана.
блаженство
@blissfool Думаю, тогда это не будет правильным способом обнаружения мобильных устройств.
Нео Морина
К сожалению нет. Но это все еще может быть жизнеспособным вариантом для очень ограниченного варианта использования.
Блиссфул
Никогда не пишите код, основанный на исключении, которое в любом случае наверняка будет выброшено ...
Пабло
@Sivic выдается только тогда, когда TouchEvent не существует, а код выше перехватывает его и возвращает false. Это не относится к мобильным устройствам, планшетам или другим устройствам с сенсорным экраном.
Нео Морина
5

Вот мое переосмысленное решение проблемы. Все еще не идеально. Единственное верное решение было бы, если бы производители устройств начали серьезно относиться к строкам пользовательских агентов «Mobile» и «Tablet».

window.onload = userAgentDetect;
function userAgentDetect() {
  if(window.navigator.userAgent.match(/Mobile/i)
  || window.navigator.userAgent.match(/iPhone/i)
  || window.navigator.userAgent.match(/iPod/i)
  || window.navigator.userAgent.match(/IEMobile/i)
  || window.navigator.userAgent.match(/Windows Phone/i)
  || window.navigator.userAgent.match(/Android/i)
  || window.navigator.userAgent.match(/BlackBerry/i)
  || window.navigator.userAgent.match(/webOS/i)) {
    document.body.className += ' mobile';
    alert('True - Mobile - ' + navigator.userAgent);
  } else {
    alert('False - Mobile - ' + navigator.userAgent);
  }
  if(window.navigator.userAgent.match(/Tablet/i)
  || window.navigator.userAgent.match(/iPad/i)
  || window.navigator.userAgent.match(/Nexus 7/i)
  || window.navigator.userAgent.match(/Nexus 10/i)
  || window.navigator.userAgent.match(/KFAPWI/i)) {
    document.body.className -= ' mobile';
    document.body.className += ' tablet';
    alert('True - Tablet - ' + navigator.userAgent);
  } else {
    alert('False - Tablet - ' + navigator.userAgent);
  }
}

Что происходит, когда на планшете Nexus 7 есть только строка Android UA? Сначала Mobile становится истинным, затем позже Tablet также становится истинным, но Tablet удалит строку Mobile UA из тега body.

CSS:

body.tablet { background-color: green; }
body.mobile { background-color: red; }

alertдобавлены линии для развития. Консоль Chrome может эмулировать многие портативные устройства. Проверьте там.

РЕДАКТИРОВАТЬ:

Просто не используйте это, используйте функцию обнаружения вместо этого. Существует так много устройств и брендов, что нацеленность на бренд НИКОГДА не будет правильным решением.

Lanti
источник
4

Я советую вам проверить http://wurfl.io/

В двух словах, если вы импортируете крошечный файл JS:

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

у вас останется объект JSON, который выглядит следующим образом:

{
 "complete_device_name":"Google Nexus 7",
 "is_mobile":true,
 "form_factor":"Tablet"
}

(это предполагает, что вы используете Nexus 7, конечно), и вы сможете делать такие вещи, как:

if(WURFL.form_factor == "Tablet"){
    //dostuff();
}

Это то, что вы ищете.

Отказ от ответственности: я работаю в компании, которая предлагает этот бесплатный сервис. Спасибо.

Лука Пассани
источник
1
И почему это не распознает сафари на iphone?
Амит
Можете ли вы рассказать о том, какой браузер вы используете (точная строка UA будет идеальной), какие данные вы получаете и чего ожидаете?
Лука Пассани,
Я тоже пробовал wurfl, у меня на iPhone 5C работает IOS 11.2. Safari не признает мобильный браузер. Я ожидаю использовать «is_mobile»: true, а затем «form_factor»: смартфон, и он тоже не возвращается.
Майк Уэллс
Мне пришлось обратиться к гуру мобильных данных в компании, и они сказали, что ОС 11.2 не работает на 5C. Самым низким устройством является 5S. Так что что-то не так в том, что вы написали. Не стесняйтесь связаться с ScientiaMobile в автономном режиме, чтобы проверить, где может быть отключение. Спасибо
Лука
4

вот один вкладыш

function isMobile() {
  return (typeof window.orientation !== "undefined") || (navigator.userAgent.indexOf('IEMobile') !== -1);
};
Рик Энсисо
источник
3

Зависит от варианта использования. Все мобильные устройства требуют батареи. Если вы ищете вычислительную мощность без разряда батареи, используйте API состояния батареи :

navigator.getBattery().then(battery => {
  battery.charging ? 'charging' : 'not charging';
});

Если вы ищете презентационное использование matchMedia, которое возвращает логическое значение:

if (window.matchMedia("(min-width: 400px)").matches) {
  /* the viewport is at least 400 pixels wide */
} else {
  /* the viewport is less than 400 pixels wide */
}

Или объедините их для еще большего удобства пользователей на планшетных устройствах.

Джош Хабдас
источник
Обратите внимание, что API состояния батареи удаляется из браузеров.
Sora2455
API состояния батареи удален из Firefox, но остается рекомендацией кандидата W3C с июля 2016 года , продолжает функционировать в популярных браузерах и полезен при формировании опыта.
Джош Хабдас
2

Вот решение ECMAScript 6 (готов к написанию TypeScript)

public isMobile(): boolean {
  let check = false;
  ((a => {
      if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true;
      }))(navigator.userAgent || navigator.vendor);
  return check;
 }
0x1ad2
источник
почему бы просто не вернуть ifусловие вместо всей этой checkпеременной?
Вик
2

Существует простая хитрость, чтобы определить, является ли это мобильным устройством или нет. Просто проверьте, существует ли событие ontouchstart :

function isMobile()
{
    return "ontouchstart" in window;
}
Мартин Уитке
источник
3
Не будет работать с ноутбуками и декстопами с сенсорными мониторами. Также будет проблема с гибридными ПК, такими как Surface. Меньше проблем с настольными компьютерами, но в настоящее время продается больше ноутбуков с сенсорным экраном.
Блиссфул
2

Я сталкивался с некоторыми сценариями, где вышеупомянутые ответы не работают для меня. Итак, я придумал это. Может быть полезным для кого-то.

if(/iPhone|iPad|iPod|Android|webOS|BlackBerry|Windows Phone/i.test(navigator.userAgent)
 || screen.availWidth < 480){
//code for mobile
}

Это зависит от вашего варианта использования. Если вы сосредоточены на использовании экрана screen.availWidth, или вы можете использовать, document.body.clientWidthесли вы хотите сделать рендеринг на основе документа.

Thyagarajan C
источник
1

Лучшее должно быть:

var isMobile = (/Mobile/i.test(navigator.userAgent));

Но, как говорит Йоав Барни ...

// Seem legit
var isMobile = ('DeviceOrientationEvent' in window || 'orientation' in window);
// But with my Chrome on windows, DeviceOrientationEvent == fct()
if (/Windows NT|Macintosh|Mac OS X|Linux/i.test(navigator.userAgent)) isMobile = false;
// My android have "linux" too
if (/Mobile/i.test(navigator.userAgent)) isMobile = true;

После этих 3 тестов, я надеюсь, что вар isMobile ... хорошо

molokoloco
источник
> У мобильного Firefox на
андроиде
1
Извините .. хорошо для меня это работает хорошо, как сейчас. "if (Modernizr.touch) / * ... * /" и продолжай ...
molokoloco
Просто интересно, как Modernizr.touch будет работать на сенсорном настольном устройстве.
B2K
Чтобы сделать его более элегантным, вы должны сделать весь код в одном блоке if-else if-else if.
Heitor
1

Вот он полная функция

function isMobile(){
    return (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino|android|ipad|playbook|silk/i.test(navigator.userAgent||navigator.vendor||window.opera)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test((navigator.userAgent||navigator.vendor||window.opera).substr(0,4)))
}

jQuery.noConflict();
jQuery(document).ready(function(){
    if(isMobile()) alert("Mobile"); else alert("Not Mobile");
});
Дэвид Латти
источник
.substr (0,4) возвращает первые 4 буквы. Как он обнаруживает "Android. + Мобильный"?
гонщик
1
@raacer на самом деле в ответе есть два регулярных выражения (оба в одной строке) - первое проверяет всю строку UA и ищет android, mobile и т. д., а второе проверяет только первые 4 символа UA ,
JackW
1
//true / false
function isMobile()
{
   return (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ); 
}

Также вы можете следовать этому руководству, чтобы обнаружить определенный мобильный телефон. Нажмите здесь .

gtzinos
источник
Пожалуйста, добавьте Mobileв свой RX
oriadam
1

как насчет использования "window.screen.width"?

if (window.screen.width < 800) {
// do something
}

или

if($(window).width() < 800) {
//do something
}

Я думаю, это лучший способ, потому что каждый день появляется новое мобильное устройство!

(хотя я думаю, что это не поддерживается старыми браузерами, но попробуйте :))

Ахмад Юсеф
источник
1
Как насчет ландшафта?
Эрик Вуду,
1
Это не очень полезно для определенных сценариев. Если размер настольного браузера изменен, он может быть неправильно определен как мобильный браузер
toing_toing
ПК принципиально отличается от мобильных устройств по удобству использования, ужасный ответ !!
Heitor
1

Обратите внимание, что большинство мобильных устройств нового поколения теперь имеют разрешение более 600x400. то есть айфон 6 ....

Доказательство теста: запускал самые последние и самые последние посты здесь, с необязательной проверкой после запуска, например так:

(function(a){
    window.isMobile = (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))
})(navigator.userAgent||navigator.vendor||window.opera);

alert("This browser was found to be a % browser.", window.isMobile ? 'mobile' : 'desktop');

Каким-то образом следующие результаты были возвращены в следующих приложениях браузера. Технические характеристики: iPhone 6S, iOS 10.3.1.

Safari (последняя версия): обнаружен как мобильный.

Chrome (последний): не обнаружил его как мобильный.

Итак, я тогда протестировал предложение от Lanti ( https://stackoverflow.com/a/31864119/7183483 ), и оно вернуло правильные результаты (мобильные для всех устройств iOS и настольные для моего Mac). Поэтому я немного отредактировал его, поскольку он будет срабатывать дважды (как для мобильных устройств, так и для планшетов). Затем я заметил при тестировании на iPad, что он также вернулся как мобильный, что имеет смысл, так как параметры, которые Lantiпроверяет ОС больше всего на свете. Поэтому я просто переместил в планшетный чек инструкцию IF для мобильного чека, которая вернула бы мобильный, если проверка планшета была отрицательной, а для планшета - в противном случае. Затем я добавил условие else для мобильной проверки, чтобы он возвращался как настольный компьютер / ноутбук, так как оба соответствуют требованиям, но затем заметил, что браузер определяет марку процессора и ОС. Поэтому я добавил то, что возвращается туда как часть оператора if if. В довершение я добавил предостерегающее заявление else, если ничего не было обнаружено. См. Ниже, скоро будет обновление с тестом на ПК с Windows 10.

О, и я также добавил переменную 'debugMode', чтобы легко переключаться между отладкой и обычной компиляцией.

Отказ от ответственности: Полный кредит Lanti , а также то, что это не было проверено на планшетах Windows ..., которые могут вернуть настольный компьютер / ноутбук, так как ОС является чистой Windows. Проверю, как только найду друга, который его использует.

function userAgentDetect() {
    let debugMode = true;
    if(window.navigator.userAgent.match(/Mobile/i)
        || window.navigator.userAgent.match(/iPhone/i)
        || window.navigator.userAgent.match(/iPod/i)
        || window.navigator.userAgent.match(/IEMobile/i)
        || window.navigator.userAgent.match(/Windows Phone/i)
        || window.navigator.userAgent.match(/Android/i)
        || window.navigator.userAgent.match(/BlackBerry/i)
        || window.navigator.userAgent.match(/webOS/i)) {
        if (window.navigator.userAgent.match(/Tablet/i)
            || window.navigator.userAgent.match(/iPad/i)
            || window.navigator.userAgent.match(/Nexus 7/i)
            || window.navigator.userAgent.match(/Nexus 10/i)
            || window.navigator.userAgent.match(/KFAPWI/i)) {
            window.deviceTypeVar = 'tablet';
            if (debugMode === true) {
                alert('Device is a tablet - ' + navigator.userAgent);
            }
        } else {
            if (debugMode === true) {
                alert('Device is a smartphone - ' + navigator.userAgent);
            };
            window.deviceTypeVar = 'smartphone';
        }
    } else if (window.navigator.userAgent.match(/Intel Mac/i)) {
        if (debugMode === true) {
            alert('Device is a desktop or laptop- ' + navigator.userAgent);
        }
        window.deviceTypeVar = 'desktop_or_laptop';
    } else if (window.navigator.userAgent.match(/Nexus 7/i)
        || window.navigator.userAgent.match(/Nexus 10/i)
        || window.navigator.userAgent.match(/KFAPWI/i)) {
        window.deviceTypeVar = 'tablet';
        if (debugMode === true) {
            alert('Device is a tablet - ' + navigator.userAgent);
        }
    } else {
        if (debugMode === true) {
            alert('Device is unknown- ' + navigator.userAgent);
        }
        window.deviceTypeVar = 'Unknown';
    }
}
jlmurph
источник
1

Это всего лишь порт es6 принятого ответа, который я использую в своем проекте. Обратите внимание, что это также включает в себя таблетки.

export const isMobile = () => {
  const vendor = navigator.userAgent || navigator.vendor || window.opera;

  return !!(
    /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(
      vendor
    ) ||
    /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk\/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i.test(
      vendor.substr(0, 4)
    )
  );
};
И я
источник
1

return 'ontouchstart' in window && window.screen.availWidth < 768

Как насчет этого, он расширяет ответ выше, но также проверяет размер экрана

Дейв Кин
источник
1

Используя Regex (от detectmobilebrowsers.com ):

/* eslint-disable */
export const IS_MOBILE = (function (a) {
  return (
    /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i
      .test(
        a.substr(0,4)
      )
  )
  // @ts-ignore
})(navigator.userAgent || navigator.vendor || window.opera)
/* eslint-enable */
Илья Зеленько
источник
0

Это также может быть решением.

var isMobile = false; //initiate as false

  // device detection
  if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) 
  || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,4))) isMobile = true;

  console.log('Mobile device:'+isMobile);

  var doc_h = $(document).height(); // returns height of HTML document
  var doc_w = $(document).width(); // returns width of HTML document
  console.log('Height: '+doc_h);
  console.log('width: '+doc_w);

  var iPadVertical = window.matchMedia("(width: 768px) and (height: 1024px) and (orientation: portrait)");
  var iPadHoricontal = window.matchMedia("(width: 1024px) and (height: 767px) and (orientation: landscape)");

  console.log('Height: '+doc_h);
  console.log('width: '+doc_w);

  if (iPadVertical.matches) {
      console.log('Ipad vertical detected');
  }else if (iPadHoricontal.matches){
      console.log('Ipad horicontal detected');
  }else {
      console.log('No Ipad');
  }

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

Friis1978
источник