Как определить, поддерживает ли устройство поддержку мыши?
В настоящее время я использую следующий тест (снятый с Modernizr) для обнаружения поддержки касания:
function is_touch_device() {
var bool;
if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
bool = true;
} else {
injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function(node) {
bool = node.offsetTop === 9;
});
}
return bool;
}
Но некоторые устройства управляются прикосновением и мышью, поэтому я хочу, чтобы отдельная функция обнаруживала, поддерживает ли устройство поддержку мыши. Какой хороший способ сделать эту проверку?
В конечном итоге мое намерение состоит в том, чтобы сделать это:
if(is_touch_device())
if(has_mouse_support())
if(is_touch_device() && has_mouse_support())
Ответы
Ответ 1
Там CSS-медиа только для этого!
Вы можете проверить, есть ли на каком-либо устройстве мышь, получив значение pointer
CSS media media:
if (matchMedia('(pointer:fine)').matches) {
// Device has a mouse
}
Поскольку это CSS, вам даже не нужно использовать JavaScript:
@media (pointer: fine) {
/* Rules for devices with mouse here */
}
Ответ 2
В настоящее время я использую следующее (jQuery), и я еще не обнаружил недостатков на определенных устройствах
$(window).bind('mousemove.hasMouse',function(){
$(window).unbind('.hasMouse');
agent.hasMouse=true;
}).bind('touchstart.hasMouse',function(){
$(window).unbind('.hasMouse');
agent.hasMouse=false;
});
Объяснение: Мышиные устройства (также ноутбуки с сенсорным экраном) сначала запускают mousemove, прежде чем они смогут запускать touchstart, а hasMouse - TRUE. Сенсорные устройства (также, например, iOS, который запускает mousemove) FIRST fire touchstart при щелчке, а затем mousemove. Тогда почему hasMouse будет установлен в FALSE.
Единственный улов в том, что это зависит от взаимодействия с пользователем, значение будет правильным только после перемещения мыши или сенсорного экрана, поэтому нельзя надеяться на использование при загрузке страницы.
Ответ 3
Как упоминалось в комментариях к вопросу, в частности, https://github.com/Modernizr/Modernizr/issues/869, пока нет хорошего ответа.
Ответ 4
var clickHandler = (isMouseEventSupported('click') ? 'click' : 'touchstart');
function isMouseEventSupported(eventName) {
var element = document.createElement('div');
eventName = 'on' + eventName;
var isSupported = (eventName in element);
if (!isSupported) {
element.setAttribute(eventName, 'return;');
isSupported = typeof element[eventName] == 'function';
}
element = null;
return isSupported;
}
Это код моего друга/коллеги, и он основывал его на: http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
Ответ 5
Нет прямого способа узнать, вам придется ждать события касания или события мыши.
Предполагая, что вы хотите обнаружить либо мышь, либо коснуться, вы можете сделать следующее: прослушать touchstart
и mousemove
(последняя может срабатывать на сенсорных устройствах без фактической мыши). Кто бы ни стрелял первым, на 99% должен быть тем, что вы ищете.
Это не принимает учетные устройства, которые на самом деле имеют оба.
document.addEventListener('mousemove', onMouseMove, true)
document.addEventListener('touchstart', onTouchStart, true)
function onTouchStart(){
removeListeners()
// touch detected: do stuff
}
function onMouseMove(){
removeListeners()
// mouse detected: do stuff
}
function removeListeners(){
document.removeEventListener('mousemove', onMouseMove, true)
document.removeEventListener('touchstart', onTouchStart, true)
}
Ответ 6
Ответ от @josemmo не работает для меня: на телефоне Android с подключенной мышью matchMedia('(pointer:fine)').matches
не совпадает.
К счастью, у меня получился другой медиа-запрос: hover
.
if (matchMedia('(hover:hover)').matches) {
// Device has a mouse
}