Виявлення пристроїв із сенсорним екраном за допомогою Javascript


129

Як у JavaScript / jQuery, як я можу виявити, чи є у клієнтського пристрою миша?

У мене є сайт, який підсуває невелику інформаційну панель, коли користувач наводить курсор миші на предмет. Я використовую jQuery.hoverIntent для виявлення наведення, але це очевидно не працює на пристроях з сенсорним екраном, як iPhone / iPad / Android. Тому на цих пристроях я хочу повернутись, щоб натиснути, щоб показати панель інформації.


6
Чому ви не можете зробити те й інше? Чи небажана функція крана на пристроях без сенсорного екрана?
EMPraptor

1
Оскільки деякі новіші пристрої не підтримують :hover, можливо, краще (при кодуванні однієї таблиці стилів для кількох пристроїв) використовувати :hoverв чисто косметичних цілях.
друдж

@empraptor: хороший момент - так, я міг би це зробити. Однак ... ми також думали про те, щоб завжди показувати панель на пристроях з сенсорним екраном - у такому випадку мені потрібно було б виявити підтримку.
Бред Робінсон

Якщо ви завжди можете показувати панель на пристроях із сенсорним екраном, чи не могли ви показувати її і на інших пристроях? Наскільки велика панель і чому бажано показувати її лише на наведення курсору / торкання?
EMPraptor

Відповіді:


12

+1 за те, що робити, hoverі те і clickінше. Іншим способом може бути використання медіа-запитів CSS та використання деяких стилів лише для менших екранів / мобільних пристроїв, які, найімовірніше, мають функцію touch / tap. Тож якщо у вас є певні стилі за допомогою CSS, і з jQuery ви перевіряєте ці елементи на властивості стилю мобільного пристрою, ви можете підключити їх, щоб написати вам певний код для мобільних пристроїв.

Дивіться тут: http://www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/


1
Гарне рішення, ви, ймовірно, могли б зробити щось на кшталт наведення перевірки з прив'язкою одного (), так що воно запускається лише в перший раз.
Тимофій Перес

Проблема полягає в тому, що якщо ви орієнтуєтесь на ширину екрана, тоді, коли ви обертаєте свій пристрій (давайте візьмемо iphone 6+ 736x414), він не матиме того ж стилю. Тож не найкраще рішення: /
antoni

266
var isTouchDevice = 'ontouchstart' in document.documentElement;

Примітка . Тільки тому, що пристрій підтримує сенсорні події, не обов'язково означає, що це виключно пристрій із сенсорним екраном. Багато пристроїв (як-от мій Asus Zenbook) підтримують події клацання та дотику, навіть якщо у них немає механізмів введення сенсорного вводу. При розробці сенсорної підтримки завжди включайте підтримку подій клацання і ніколи не вважайте, що будь-який пристрій є виключно тим чи іншим.


33
Як описано в документах Modernizr, це виявляє лише функцію веб-переглядача , а не можливість пристрою ... ви отримаєте помилково позитивний результат на пристроях без сенсорного вводу, на яких працює браузер, який працює на дотик. Я не знаю способу спонтанно визначити можливість торкання пристрою , не чекаючи лише того, що відбудеться сенсорне подія.
Стю Кокс

12
Для того щоб виявити IE 10 touch, я використовую: (window.navigator.msMaxTouchPoints || ('ontouchstart' у document.documentElement));
Олександр Келлетт

2
'ontouchstart' in document.documentElement неправильно повертає істину на BlackBerry 9300
Простіше

10
@typhon якщо програмне забезпечення (Win 8, сучасні браузери) підтримує дотик, це завжди буде правдою - навіть якщо ви працюєте на апаратному забезпеченні (настільний ПК, стандартний монітор, миша та клавіатура), яке не підтримує дотик. Тому це рішення застаріло.
Барні

1
funnyItsNotCamelCaseAsJsIsThroughout. Я маю на увазі, тепер людям потрібно буде скопіювати, вставити та відредагувати код. :)
Росс

20

Знайдено тестування на window.Touch не працює на android, але це:

function is_touch_device() {
  return !!('ontouchstart' in window);
}

Дивіться статтю: Який найкращий спосіб виявити пристрій "сенсорний екран" за допомогою JavaScript?


Це дозволяє виявляти сенсорні екрани, але будьте обережні, оскільки він також повертає ІСТИНА для ноутбуків із сенсорними екранами. Це може бути проблемою, якщо ви намагаєтеся розрізнити, чи користувач від телефону / планшета чи комп'ютера / ноутбука, оскільки для ноутбуків з сенсорним екраном він повертає ПРАВИЛЬНО.
Поєднайте

8
return (('ontouchstart' in window)
      || (navigator.maxTouchPoints > 0)
      || (navigator.msMaxTouchPoints > 0));

Причина використання maxTouchPoints разом з msMaxTouchPoints:

Microsoft заявила, що починаючи з Internet Explorer 11, попередньо встановлену версію цього властивості (msMaxTouchPoints) постачальника Microsoft може бути видалена, і рекомендує замість цього використовувати maxTouchPoints.

Джерело: http://ctrlq.org/code/19616-detect-touch-screen-javascript


це працювало і працювало в інструментах для розробників google chrome, що імітують пристрій дякую
Behnam Mohammadi

7
if ("ontouchstart" in window || navigator.msMaxTouchPoints) {
    isTouch = true;
} else {
    isTouch = false;
}

Працює кожен де !!


І що це стосується миші? (власне питання)
hexalys

Це було б простішеisTouch = "ontouchstart" in window || navigator.msMaxTouchPoints;
Ендрю


4

Google Chrome, здається, повертає помилкові позитиви на цьому:

var isTouch = 'ontouchstart' in document.documentElement;

Я припускаю, що це має відношення до його здатності "емуляція подій, що торкаються" (F12 -> налаштування в правому нижньому куті -> вкладка "відміни" -> останній прапорець). Я знаю, що це вимкнено за замовчуванням, але саме з цим я пов’язую зміну результатів (метод "in", який використовується для роботи в Chrome). Однак, напевно, це працює, наскільки я перевірив:

var isTouch = !!("undefined" != typeof document.documentElement.ontouchstart);

Усі браузери, у яких я запускаю цей код у стані, typeof є "об'єктом", але я відчуваю себе впевненіше, знаючи, що це все, але не визначено :-)

Тестовано на IE7, IE8, IE9, IE10, Chrome 23.0.1271.64, Chrome для iPad 21.0.1180.80 та iPad Safari. Було б здорово, якби хтось зробив ще кілька тестів і поділився результатами.


Обидва способи повертають помилкові позитиви на комп'ютері Win 8 з FF 23 та Chrome 28. Це завжди так чи це тому, що я колись мав сенсорний екран, приєднаний до цього комп'ютера - можливо, перед встановленням FF і Chrome - але вже не? У мене не встановлено параметр "емуляція сенсорних подій".
тайфон

А, це завжди боротьба з новим обладнанням. Браузерам доводиться працювати з шарами абстракції ОС…, які не завжди реалізують усе… словом, з JS ви повинні покладатися на браузер :) Ніколи не існує універсального способу.
Еш

І те, і інше повертається у Ubuntu Firefox на ноутбуці, що не стосується дотику.
NoBugs

4

Написав це для одного з моїх сайтів і, мабуть, це найбезпечніше рішення. Тим більше, що навіть Modernizr може отримати помилкові позитиви при виявленні дотику.

Якщо ви використовуєте jQuery

$(window).one({
  mouseover : function(){
    Modernizr.touch = false; // Add this line if you have Modernizr
    $('html').removeClass('touch').addClass('mouse');
  } 
});

або просто чистий JS ...

window.onmouseover = function(){ 
    window.onmouseover = null;
    document.getElementsByTagName("html")[0].className += " mouse";
}

4
Але будьте обережні: принаймні iPad теж
кидає на себе миші

14
Чорт ти Apple!
Тимофій Перес

І люди, які використовують IE на планшеті Windows, можуть скористатися як сенсорним, так і мишем.
Sebazzz

Це повідомлення було зроблено до появи планшета Windows.
Тимофій Перес

@ s427 - Перевірка IE ... просто зробіть перевірку на IE8. Я не думаю, що мобільних пристроїв із <= IE8 немає.
Тимофій Перес

4

Для мого першого повідомлення / коментаря: Ми всі знаємо, що "сенсорний запуск" спрацьовує перед натисканням. Ми також знаємо, що коли користувач відкриє вашу сторінку, він: вона: 1) перемістить мишу 2) натисніть 3) торкніться екрана (для прокрутки, або ... :))

Спробуємо щось:

// -> Початок: jQuery

var hasTouchCapabilities = 'ontouchstart' in window && (navigator.maxTouchPoints || navigator.msMaxTouchPoints);
var isTouchDevice = hasTouchCapabilities ? 'maybe':'nope';

//attach a once called event handler to window

$(window).one('touchstart mousemove click',function(e){

    if ( isTouchDevice === 'maybe' && e.type === 'touchstart' )
        isTouchDevice = 'yes';
});

// <- Кінець: jQuery

Гарного дня!


3

Я випробував наступний код, зазначений вище в дискусії

 function is_touch_device() {
    return !!('ontouchstart' in window);
 }

працює на android Mozilla, хром, Opera, андроїд браузер за замовчуванням та сафарі на iphone ... все позитивне ...

здається солідним для мене :)


Супер просто і добре працює для мене. Тестовано на Android (стара Galaxy Note) та на емуляторах (Chrome) та на iPad.
Ральф

Повертає хибний позитив для Chrome.
Джеймс


2

Це працює для мене:

function isTouchDevice(){
    return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}

1
на скільки платформ, веб-переглядачів, ОС ', пристроїв ви протестували?
BerggreenDK

1
FF, Chrome, Safari на Android та iOS (iPad)
Turtletrail

1
Досить приємно. Я щойно тестував на робочому столі і отримав багато "невизначених", що робить структуру IF трохи хиткою. Якщо ви трохи відрегулюєте своє повернене значення: Тоді у вас є правда чи хибність :-)
BerggreenDK

2
У Chrome "ontouchstart" у вікні вірно на моєму ПК без сенсорного екрана, тому це не працює. Як зазначалося раніше, це тестує, чи браузер може працювати на дотику. Також true == нічого не робить, і його слід опустити.
rakensi

1
Коли я спробую це в Chrome із вбудованим емулятором, він виявить дотик, коли він увімкнений в емуляторі, і не буде виявляти дотик при його вимкненні. Так добре для мене працює. Але: я використовую коротку версію Prasad (нижче), яка не використовує || в коді Turtletrail. І: Мені байдуже, чи працює він на 100% пристроїв. 99% зробить для мене.
Ральф

1

Якщо ви використовуєте Modernizr , це дуже просто у використанні, Modernizr.touchяк згадувалося раніше.

Однак я вважаю за краще використовувати комбінацію Modernizr.touchта тестування агента користувача, лише для того, щоб бути безпечним.

var deviceAgent = navigator.userAgent.toLowerCase();

var isTouchDevice = Modernizr.touch || 
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/)  || 
deviceAgent.match(/(iemobile)/) || 
deviceAgent.match(/iphone/i) || 
deviceAgent.match(/ipad/i) || 
deviceAgent.match(/ipod/i) || 
deviceAgent.match(/blackberry/i) || 
deviceAgent.match(/bada/i));

if (isTouchDevice) {
        //Do something touchy
    } else {
        //Can't touch this
    }

Якщо ви не використовуєте Modernizr, ви можете просто замінити Modernizr.touchфункцію вище('ontouchstart' in document.documentElement)

Також зауважте, що тестування агента користувача iemobileдасть вам ширший спектр виявлених мобільних пристроїв Microsoft, ніж Windows Phone.

Дивіться також це питання


2
Зараз однакова відповідь на 4 запитання ... і це не є вирішенням питання, яке він задає.
jycr753

1
Я вважаю, що це відповідає на питання тут
Пітер-Пан

це не відповідь, але це натяк, на який я думаю, для кого хочуть виявити, чи пристрій є дотиковим до того, як користувач торкнеться його
Shahadat Hossain Khan

1

У jQuery Mobile ви можете просто зробити:

$.support.touch

Не знаю, чому це так недокументовано .. але це безпечно для веб-переглядачів (останні 2 версії сучасних браузерів).


0

Як вже було сказано, пристрій може підтримувати введення миші та сенсорного введення. Дуже часто виникає питання не "що підтримується", а "що зараз використовується".

У цьому випадку ви можете просто зареєструвати події миші (включаючи слухача курсора) та торкнутися подій.

element.addEventListener('touchstart',onTouchStartCallback,false);

element.addEventListener('onmousedown',onMouseDownCallback,false);

...

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

Зауважте, що дотик може запускати слухачів як дотику, так і миші. Однак сенсорний слухач виходить першим і може запобігти наступним слухачам миші запускати дзвінки event.preventDefault().

function onTouchStartCallback(ev) {
    // Call preventDefault() to prevent any further handling
    ev.preventDefault();
    your code...
}

Подальше читання тут .


-3

Для розробки iPad я використовую:

  if (window.Touch)
  {
    alert("touchy touchy");
  }
  else
  {
    alert("no touchy touchy");
  }

Потім я можу вибірково прив’язуватися до подій на основі дотику (наприклад, ontouchstart) або подій на основі миші (наприклад, onmousedown). Я ще не тестував на android.


1
Це не працює з Opera Mobile 10 або Internet Explorer Mobile 6 (Windows Mobile 6.5).
подвійнийJ20

4
поганий кроссбоузер / кросова ОС / поради щодо крос-платформи.
BerggreenDK
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.