Как лучше всего обнаружить устройство с «сенсорным экраном» с помощью JavaScript? - PullRequest
375 голосов
/ 27 января 2011

Я написал плагин jQuery для использования на настольных и мобильных устройствах. Я задавался вопросом, есть ли способ с JavaScript, чтобы обнаружить, если устройство имеет возможность сенсорного экрана. Я использую jquery-mobile.js для обнаружения событий сенсорного экрана, и он работает на iOS, Android и т. Д., Но я также хотел бы написать условные операторы, основанные на том, имеет ли устройство пользователя сенсорный экран.

Это возможно?

Ответы [ 36 ]

1 голос
/ 20 мая 2014

Я также много боролся с различными вариантами того, как определить в Javascript, отображается страница на устройстве с сенсорным экраном или нет.ИМО, на данный момент не существует никакой реальной возможности правильно ее определить.Браузеры либо сообщают о событиях касания на настольных компьютерах (поскольку ОС может быть готова к касанию), либо некоторые решения работают не на всех мобильных устройствах.

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

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

1 голос
/ 11 апреля 2014

Поддерживаются все браузеры, кроме Firefox для настольных компьютеров всегда TRUE , поскольку Firefox для настольных ПК поддерживает адаптивный дизайн для разработчиков, даже если вы нажмете сенсорную кнопку или нет!

Я надеюсь, что Mozilla исправит это в следующей версии.

Я использую рабочий стол Firefox 28.

function isTouch()
{
    return !!("ontouchstart" in window) || !!(navigator.msMaxTouchPoints);
}
1 голос
/ 21 мая 2014

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

Я создал jsFiddle

function isTouchDevice(){
    if(Modernizr.hasEvent('touchstart') || navigator.userAgent.search(/Touch/i) != -1){
         alert("is touch");
            return true;
         }else{
            alert("is not touch");
            return false;
    }
}
1 голос
/ 17 июня 2017

проблема

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

Сенсорные устройства также запускают mousemove на кране.

Решение

  1. Предположим, что прикосновение ложно при загрузке.
  2. Подождите, пока не произойдет событие touchstart, затем установите для него значение true.
  3. Если сенсорный запуск сработал, добавьте обработчик перемещения мыши.
  4. Если время между двумя событиями перемещения мыши было менее 20 мс, предположим, что они используют мышь в качестве входных данных. Удалите событие, так как оно больше не нужно, и mousemove - дорогостоящее событие для устройств мыши.
  5. Как только сенсорный запуск запускается снова (пользователь вернулся к использованию сенсорного ввода), для переменной устанавливается значение true. И повторите процесс, чтобы он определялся динамично. Если каким-то чудом мышиный ход сработал дважды при прикосновении до абсурда быстро (в моем тестировании это практически невозможно сделать в течение 20 мс), следующий сенсорный запуск вернет его в значение true.

Проверено на Safari iOS и Chrome для Android.

Примечание: не уверен на 100% в событиях указателя для MS Surface и т. Д.

Кодовая демонстрация


const supportsTouch = 'ontouchstart' in window;
let isUsingTouch = false;

// `touchstart`, `pointerdown`
const touchHandler = () => {
  isUsingTouch = true;
  document.addEventListener('mousemove', mousemoveHandler);
};

// use a simple closure to store previous time as internal state
const mousemoveHandler = (() => {
  let time;

  return () => {
    const now = performance.now();

    if (now - time < 20) {
      isUsingTouch = false;
      document.removeEventListener('mousemove', mousemoveHandler);
    }

    time = now;
  }
})();

// add listeners
if (supportsTouch) {
  document.addEventListener('touchstart', touchHandler);
} else if (navigator.maxTouchPoints || navigator.msMaxTouchPoints) {
  document.addEventListener('pointerdown', touchHandler);
}
1 голос
/ 28 ноября 2015

jQuery v1.11.3

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

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

Помимо этого поста и Обнаружение устройств с сенсорным экраном с помощью Javascript , я нашел этот пост Патрика Лаука чрезвычайно полезным: https://hacks.mozilla.org/2013/04/detecting-touch-its-the-why-not-the-how/

Вот код ...

$(document).ready(function() {
//The page is "ready" and the document can be manipulated.

    if (('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0))
    {
      //If the device is a touch capable device, then...
      $(document).on("touchstart", "a", function() {

        //Do something on tap.

      });
    }
    else
    {
      null;
    }
});

Важно! Метод *.on( events [, selector ] [, data ], handler ) должен иметь селектор, обычно элемент, который может обрабатывать событие "touchstart" или любое другое подобное событие, связанное с касаниями. В данном случае это элемент гиперссылки «а».

Теперь вам не нужно обрабатывать обычное нажатие мыши в JavaScript, потому что вы можете использовать CSS для обработки этих событий, используя селекторы для элемента «a» гиперссылки, например:

/* unvisited link */
a:link 
{

}

/* visited link */
a:visited 
{

}

/* mouse over link */
a:hover 
{

}

/* selected link */
a:active 
{

}

Примечание: есть и другие селекторы ...

1 голос
/ 09 июля 2015

Практическим ответом, по-видимому, является тот, который учитывает контекст:

1) Публичный сайт (без входа в систему)
Код пользовательского интерфейса для совместной работы с обоими вариантами.

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

Jquery для добавления только на страницу входа:

$('#istouch').val(1); // <-- value will be submitted with login form

if (window.addEventListener) {
    window.addEventListener('mousemove', function mouseMoveListener(){
        // Update hidden input value to false, and stop listening
        $('#istouch').val(0); 
        window.removeEventListener('mousemove', mouseMoveListener);
    });
} 

(от + 1 до @Dave Burt и +1 до @Martin Lantzsch в ответах)

0 голосов
/ 28 мая 2019
var isTouchDevice =
    (('ontouchstart' in window) ||
    (navigator.MaxTouchPoints > 0) ||
    (navigator.msMaxTouchPoints > 0));
if(!isTouchDevice){
    /* Code for touch device /*
}else{
    /* Code for non touch device */
}

Веселись!

0 голосов
/ 29 июня 2013

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

var touchEnabled = false;
$(document.body).one('touchstart',
    function(e){
        touchEnabled=true;
        $(document.documentElement).addClass("touch");
        // other touch related init 
        //
    }
);
0 голосов
/ 22 сентября 2017

это так просто, если вы протестируете, что touchstart поддерживается в document.documentElement

var x = 'touchstart' in document.documentElement;
console.log(x)
// return true if is supported
// else return false
0 голосов
/ 30 августа 2017
$.support.touch ? "true" : "false";
...