Обнаружение устройств с сенсорным экраном с помощью Javascript

129

Как в Javascript / jQuery определить, есть ли на клиентском устройстве мышь?

У меня есть сайт, на котором появляется небольшая информационная панель, когда пользователь наводит указатель мыши на элемент. Я использую jQuery.hoverIntent для обнаружения зависания, но это явно не работает на устройствах с сенсорным экраном, таких как iPhone / iPad / Android. Поэтому на этих устройствах я хотел бы вернуться к нажатию, чтобы отобразить информационную панель.

Брэд Робинсон
источник
6
Почему вы не можете сделать и то, и другое? Является ли функция крана нежелательной в устройствах без сенсорного экрана?
EMPraptor
1
Поскольку некоторые новые устройства не поддерживают :hover, вероятно, лучше (при кодировании одной таблицы стилей для нескольких устройств) использовать :hoverчисто в косметических целях.
drudge
@empraptor: хороший момент - да, я мог бы это сделать. Однако ... мы также думали о том, чтобы всегда показывать панель на устройствах с сенсорным экраном - в этом случае мне нужно было бы иметь возможность обнаруживать поддержку.
Брэд Робинсон,
Если вы всегда можете показать панель на устройствах с сенсорным экраном, не могли бы вы показать ее и на других устройствах? Насколько велика панель и почему желательно, чтобы она отображалась только при наведении / тапе?
EMPraptor

Ответы:

12

+1 за выполнение hoverи то и clickдругое. Еще один способ - использовать медиа-запросы CSS и использовать некоторые стили только для небольших экранов / мобильных устройств, которые, скорее всего, будут иметь функцию касания / касания. Итак, если у вас есть определенные стили через CSS, а из jQuery вы проверяете эти элементы на предмет свойств стиля мобильного устройства, вы можете подключиться к ним, чтобы написать свой код для мобильных устройств.

Смотрите здесь: http://www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/

Мойн Заман
источник
1
Хорошее решение, вы, вероятно, могли бы сделать что-то вроде проверки наведения с привязкой one (), чтобы она срабатывала только в первый раз.
Тимоти Перес,
Проблема в том, что если вы ориентируетесь по ширине экрана, то при повороте устройства (возьмем iphone 6+ 736x414) оно не будет иметь тот же стиль. Так что не лучшее решение: /
antoni
266
var isTouchDevice = 'ontouchstart' in document.documentElement;

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

KevBurnsJr
источник
33
Как описано в документации Modernizr, это определяет только возможности браузера , но не возможности устройства ... вы получите ложноположительный результат на устройствах без сенсорного ввода, на которых запущен браузер с сенсорным управлением. Я не знаю способа определить возможность касания устройства изначально, не дожидаясь, пока произойдет событие касания.
Стю Кокс,
12
Чтобы также обнаружить касание IE 10, я использую: (window.navigator.msMaxTouchPoints || ('ontouchstart' в document.documentElement));
Александр Келлетт
2
'ontouchstart' in document.documentElement неверно возвращает истину на BlackBerry 9300
Simpler
10
@typhon, если программное обеспечение (Win 8, современные браузеры) поддерживает сенсорное управление, это всегда будет так - даже если вы используете оборудование (рабочий стол, стандартный монитор, мышь и клавиатура), которое не поддерживает сенсорный ввод. Следовательно, это решение устарело.
Barney
1
funnyItsNotCamelCaseAsJsIsThroughout. Я имею в виду, что теперь людям нужно будет копировать, вставлять И редактировать код ... :)
Росс
20

Найдено тестирование для window.Touch не работает на android, но это работает:

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

См. Статью: Как лучше всего обнаружить устройство с сенсорным экраном с помощью JavaScript?

hallodom
источник
Это обнаруживает сенсорные экраны, но будьте осторожны, потому что возвращает ИСТИНА и для ноутбуков с сенсорными экранами. Это может быть проблемой, если вы пытаетесь определить, принадлежит ли пользователь телефону / планшету ИЛИ компьютеру / ноутбуку, потому что для ноутбуков с сенсорным экраном он возвращает ИСТИНА.
Объединить
8
return (('ontouchstart' in window)
      || (navigator.maxTouchPoints > 0)
      || (navigator.msMaxTouchPoints > 0));

Причина использования maxTouchPoints вместе с msMaxTouchPoints:

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

Источник: http://ctrlq.org/code/19616-detect-touch-screen-javascript

пользователь
источник
это сработало и сработало в инструментах разработчика Google Chrome, имитирующих устройство, спасибо
Бехнам Мохаммади,
7
if ("ontouchstart" in window || navigator.msMaxTouchPoints) {
    isTouch = true;
} else {
    isTouch = false;
}

Работает везде !!

Кодовый шпион
источник
И при чем тут мышь? (актуальный вопрос)
hexalys 01
Было бы проще сделатьisTouch = "ontouchstart" in window || navigator.msMaxTouchPoints;
Андрей
4

Я использую:

if(jQuery.support.touch){
    alert('Touch enabled');
}

в jQuery Mobile 1.0.1

отметка
источник
2
jQuery рекомендует не использовать jQuery.support в пользу Modernizr ( modernizr.com ): ссылка - api.jquery.com/jQuery.support -
Джонатан Марзулло
4

Google Chrome, похоже, возвращает ложные срабатывания по этому поводу:

var isTouch = 'ontouchstart' in document.documentElement;

Я полагаю, это как-то связано с его способностью «эмулировать сенсорные события» (F12 -> настройки в правом нижнем углу -> вкладка «переопределяет» -> последний флажок). Я знаю, что по умолчанию он выключен, но это то, с чем я связываю изменение результатов (метод «in», используемый для работы в Chrome). Однако, насколько я тестировал, это, похоже, работает:

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

Во всех браузерах, в которых я запускал этот код, указано, что typeof является «объектом», но я уверен, что это что угодно, но не undefined :-)

Протестировано в 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 - но теперь нет? У меня нет настройки «эмулировать сенсорные события».
typhon
Эээ, это всегда борьба с новым оборудованием. Браузеры должны работать с уровнями абстракции ОС ... которые не всегда все реализуют ... короче говоря, с 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 01
Этот пост был сделан до того, как появился Windows Tablet.
Тимоти Перес
@ s427 - Fecking IE ... просто проверьте IE8. Я не думаю, что есть мобильные устройства с <= IE8.
Тимоти Перес,
4

Для моего первого поста / комментария: все мы знаем, что touchstart срабатывает перед щелчком. Мы также знаем, что когда пользователь откроет вашу страницу, он или она: 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

Хорошего дня!

silassare
источник
3

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

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

работает на android Mozilla, chrome, Opera, браузер android по умолчанию и safari на iphone ... все положительно ...

мне кажется солидным :)

Прасад
источник
Супер просто и отлично работает для меня. Проверено на Android (старый Galaxy Note) и с эмуляторами (Chrome) и на iPad.
Ральф,
Возвращает мне ложное срабатывание в Chrome.
Джеймс
3

Полезный пост в блоге по этой теме, связанный с источником Modernizr для обнаружения событий касания. Вывод: надежно обнаружить устройства с сенсорным экраном с помощью Javascript невозможно.

http://www.stucox.com/blog/you-cant-detect-a-touchscreen/

Майк С
источник
2

Это работает для меня:

function isTouchDevice(){
    return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}
Turtletrail
источник
1
На скольких платформах, браузерах, ОС, устройствах вы тестировали?
BerggreenDK
1
FF, Chrome, Safari для Android и iOS (iPad)
Turtletrail
1
Достаточно хорошо. Я только что протестировал на настольном компьютере и получил много "неопределенных", что делает структуру IF немного взломанной. Если вы немного измените возвращаемое значение, например: return true == ("ontouchstart" в окне || window.DocumentTouch && document instanceof DocumentTouch); Тогда у вас правда или ложь :-)
BerggreenDK
2
В Chrome "ontouchstart" в окне работает на моем ПК без сенсорного экрана, поэтому это не работает. Как отмечалось ранее, это проверяет, поддерживает ли браузер сенсорное управление. Кроме того, true == ничего не делает, и его следует опустить.
rakensi
1
Когда я пробую это в Chrome со встроенным эмулятором, он обнаруживает касание, когда он включен в эмуляторе, и не обнаруживает касание, когда он выключен. Так что у меня отлично работает. Но: я использую сокращенную версию Prasad (ниже), в которой не используется || в коде Turtletrail. И еще: мне все равно, работает ли он на 100% устройств. 99% мне подойдет.
Ralf
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 .

Также см. Этот вопрос SO

Питер Пэн
источник
2
Тот же ответ на 4 вопроса сейчас ... и это не решение вопроса, который он задает.
jycr753
1
Я считаю, что здесь есть ответ на вопрос
Питер-Пэн,
это не ответ, но это подсказка, я думаю, для тех, кто хочет определить, можно ли прикоснуться к устройству, прежде чем пользователь прикоснется к нему,
Шахадат Хоссейн Хан
1

В jQuery Mobile вы можете просто:

$.support.touch

Не знаю, почему это так недокументировано .. но это кроссбраузерная безопасность (последние 2 версии текущих браузеров).

Ozzie
источник
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...
}

Дополнительная информация здесь .

user3792852
источник
-3

Для разработки на iPad я использую:

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

Затем я могу выборочно привязаться к событиям касания (например, ontouchstart) или событиям, основанным на мыши (например, onmousedown). На андроиде еще не тестировал.

Холтон
источник
1
Это не работает с Opera Mobile 10 или Internet Explorer Mobile 6 (Windows Mobile 6.5).
doubleJ
4
плохой совет кроссбраузера / кросс-ОС / кросс-платформенности.
BerggreenDK