Обнаружение, что браузер не имеет мыши и только для сенсорного - PullRequest
137 голосов
/ 20 октября 2011

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

Возможность сенсорного события в браузере на самом деле не означает, что пользователь использует сенсорное устройство (например, Modernizr его не обрезает). Код, который правильно отвечает на вопрос, должен возвращать false, если на устройстве есть мышь, в противном случае - true. Для устройств с мышью и сенсорным экраном он должен возвращать false (не только сенсорный)

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

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

// Level 1


// The current answers provide a way to do that.
hasTouch();

// Returns true if a mouse is expected.
// Note: as explained by the OP, this is not !hasTouch()
// I don't think we have this in the answers already, that why I offer a bounty
hasMouse();

// Level 2 (I don't think it's possible, but maybe I'm wrong, so why not asking)

// callback is called when the result of "hasTouch()" changes.
listenHasTouchChanges(callback);

// callback is called when the result of "hasMouse()" changes.
listenHasMouseChanges(callback);

Ответы [ 24 ]

2 голосов
/ 10 февраля 2012

Tera-WURFL может рассказать вам о возможностях устройства, которое посещает ваш сайт , сравнив сигнатуру браузера с его базой данных.Посмотрите, это бесплатно!

0 голосов
/ 24 февраля 2014

Хотел бы порекомендовать сценарий, который мне помог:

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

Затем я исследовал еще немного и нашел этот код - device.js

Я использую это на веб-сайте моего клиента, чтобы обнаружитьсуществование мыши:
(<html> должен иметь класс desktop), и это кажется довольно хорошим, и для поддержки touch я просто делаю обычную проверку 'ontouchend' in document и использую информацию из обоих обнаружений, чтобы предположить конкретную вещьМне нужно.

0 голосов
/ 18 августа 2013

Провел несколько тестов на разных ПК, Linux, iPhone, Android телефонах и вкладках. Странно, что нет простого пуленепробиваемого решения. Проблема возникает, когда некоторые из них имеют Touch и мышь не по-прежнему представляют события Touch и Mouse для приложения. Поскольку мы хотим поддерживать экземпляры только для мыши и только для касания, хотим обрабатывать оба, но это вызывает двойное возникновение пользовательских взаимодействий. Если может знать, что мышь не присутствует на устройстве, то может знать, чтобы игнорировать ложные / вставленные события мыши. Попытка установки флага, если встречается MouseMove, но некоторые браузеры выдают поддельные MouseMove, а также MouseUp и MouseDown. Пробовал изучать временные метки, но решил, что это слишком рискованно. Итог: я обнаружил, что браузеры, создавшие ложные события мыши, всегда вставляли один MouseMove непосредственно перед вставленным MouseDown. В 99,99% моих случаев при работе в системе с настоящей мышью происходит несколько последовательных событий MouseMove - как минимум два. Поэтому следите за тем, встречает ли система два последовательных события MouseMove, и объявляйте, что мыши нет, если это условие никогда не выполняется. Это, вероятно, слишком просто, но работает на всех моих тестовых установках. Думаю, я буду придерживаться этого, пока не найду лучшее решение. - Джим Ш

0 голосов
/ 12 февраля 2012

Я настоятельно рекомендую против такого подхода. Подумайте об устройствах с сенсорным экраном, размером с настольный компьютер, и вам придется решать различные задачи.

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

0 голосов
/ 15 февраля 2012

Основная проблема, которую я вижу здесь, состоит в том, что большинство сенсорных устройств запускают событие мыши вместе с отвечающим на касание touch one (touchstart -> mousedown, touchmove -> mousemove и т. Д.). Только для клавиатуры, наконец, для современных, они имеют универсальный браузер, поэтому вы даже не можете обнаружить присутствие класса MouseEvent.

На мой взгляд, менее болезненным решением было бы, по моему мнению, отображать меню при запуске (с управлением «alt» для пользователей только с клавиатуры) и, возможно, сохранять выбор с помощью localStorage / cookies / serveride или еще для сохранения выбор в следующий раз, когда посетитель придет.

0 голосов
/ 03 февраля 2017

Только что нашел решение, которое я считаю довольно элегантным.

// flag as mouse interaction by default
var isMouse = true;

// detect a touch event start and flag it
$(window).on('touchstart', function () {
  // if triggers touchstart, toggle flag
  // since touch events come before mouse event / click
  // callback of mouse event will get in callback
  // `isMouse === false`
  isMouse = false;
});

// now the code that you want to write
// should also work with `mouse*` events
$('a.someClass').on('click', function () {
  if (isMouse) {
    // interaction with mouse event
    // ...
  } else {
    // reset for the next event detection
    // this is crucial for devices that have both
    // touch screen and mouse
    isMouse = true;

    // interaction with touch event
    // ...
  }
});
0 голосов
/ 03 августа 2015

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

$('body').one('touchstart.test', function(e) {
  // Remove the mousemove listener for touch devices
  $('body').off('mousemove.test');
}).one('mousemove.test', function(e) {
  // MOUSE!
});

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

0 голосов
/ 01 августа 2013

Взгляните на modenizr, одна из его функций - сенсорный

http://modernizr.com/docs/#features-misc

Хотя я не тестировал полностью, похоже, он работает очень хорошо

Также этосвязан со страницей modernizr http://www.html5rocks.com/en/mobile/touchandmouse/

0 голосов
/ 02 августа 2013

Как уже указывали другие, окончательное определение наличия у них мыши ненадежно.Это может легко измениться, в зависимости от устройства.Это определенно то, что вы не можете надежно сделать с логическим значением true или false, по крайней мере, в масштабе документа.

События касания и мыши являются исключительными.Так что это может несколько помочь при совершении различных действий.Проблема заключается в том, что события касания находятся ближе к событиям мыши вверх / вниз / перемещения, а также вызывают событие щелчка.

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

Если это так, вы можетенемного ленивый подход к обнаружению:

Событию onclick всегда будет предшествовать событие onmouseover с мышью.Поэтому обратите внимание, что мышь находится над элементом, по которому щелкнули.

Это можно сделать с помощью события onmousemove для всего документа.Вы можете использовать event.target, чтобы записать, на каком элементе находится мышь.Затем внутри событий onclick вы можете проверить, действительно ли мышь находится над элементом, по которому щелкают (или потомком элемента).

Оттуда вы можете выбрать, полагаться ли на событие click дляи оба и A или B действие в зависимости от результата.Действие B может быть ничем, если некоторые сенсорные устройства не генерируют событие щелчка (вместо этого вам придется полагаться на события ontouch *).

0 голосов
/ 02 августа 2013

Я не думаю, что можно идентифицировать устройство только для касания (насколько мне известно, конечно). Основная проблема заключается в том, что все события мыши и клавиатуры запускаются сенсорными устройствами. См. Следующий пример: оба предупреждения возвращают значение true для сенсорных устройств.

function is_touch_present() {
  return ('ontouchstart' in window) || ('onmsgesturechange' in window);
}

function is_mouse_present() {
  return (('onmousedown' in window) && ('onmouseup' in window) && ('onmousemove' in window) && ('onclick' in window) && ('ondblclick' in window) && ('onmousemove' in window) && ('onmouseover' in window) && ('onmouseout' in window) && ('oncontextmenu' in window));
}

alert("Touch Present: " + is_touch_present());
alert("Mouse Present: " + is_mouse_present());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...