Jaki jest najlepszy sposób na wykrycie urządzenia z Ekranem dotykowym za pomocą JavaScript?

Napisałem wtyczkę jQuery do użytku zarówno na komputerach, jak i urządzeniach mobilnych. Zastanawiałem się, czy istnieje sposób z JavaScript, aby wykryć, czy urządzenie ma możliwość ekranu dotykowego. Używam jQuery-mobile.js wykrywa zdarzenia na ekranie dotykowym i działa na iOS, Androidzie itp., ale chciałbym też napisać instrukcje warunkowe na podstawie tego, czy urządzenie użytkownika ma ekran dotykowy.

Czy to możliwe?

Author: Mark Amery, 2011-01-27

30 answers

Aktualizacja: przeczytaj odpowiedź blmstr poniżej przed wciągnięciem całej biblioteki wykrywania funkcji do swojego projektu. Wykrywanie rzeczywistej obsługi dotyku jest bardziej złożone, a Modernizr obejmuje tylko podstawowy przypadek użycia.

Modernizr to świetny, lekki sposób na wykrywanie wszelkiego rodzaju funkcji w dowolnej witrynie.

Po prostu dodaje klasy do elementu html dla każdej funkcji.

Możesz następnie łatwo kierować te funkcje w CSS i JS. Na przykład:

html.touch div {
    width: 480px;
}

html.no-touch div {
    width: auto;
}

I Javascript (przykład jQuery):

$('html.touch #popup').hide();
 142
Author: Alan Christopher Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:36

Aktualizacja 2021

aby zobaczyć stare odpowiedzi: Sprawdź historię. Postanowiłem zacząć od czystej karty, ponieważ wymykało się to z rąk, gdy trzymałem historię w poście.

Moja oryginalna odpowiedź mówi, że dobrym pomysłem może być użycie tej samej funkcji, której używał Modernizr, ale to już nie jest ważne, ponieważ usunęli testy "touchevents" na tym PR: https://github.com/Modernizr/Modernizr/pull/2432 ze względu na to, że jest to mylące temat.

Z tym powiedział, że powinien to być dość ok sposób wykrywania, czy przeglądarka ma "możliwości dotykowe":

function isTouchDevice() {
  return (('ontouchstart' in window) ||
     (navigator.maxTouchPoints > 0) ||
     (navigator.msMaxTouchPoints > 0));
}

Ale dla bardziej zaawansowanych przypadków użycia o wiele mądrzejsze osoby niż ja pisały na ten temat, polecam przeczytać te artykuły:

 734
Author: bolmaster2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-11 15:26:42

Ponieważ Modernizr nie wykrywa IE10 na Windows Phone 8 / WinRT, prostym, między przeglądarkowym rozwiązaniem jest:

var supportsTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints;

Musisz tylko raz sprawdzić, ponieważ urządzenie nagle nie obsługuje lub nie obsługuje dotyku, więc po prostu przechowuj go w zmiennej, aby można było z niego korzystać wiele razy bardziej efektywnie.

 123
Author: Matt Stow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-28 22:54:57

Od wprowadzenia interaction media features można po prostu zrobić:

if(window.matchMedia("(pointer: coarse)").matches) {
    // touchscreen
}

Https://www.w3.org/TR/mediaqueries-4/#descdef-media-any-pointer

Aktualizacja (ze względu na komentarze): powyższe rozwiązanie polega na wykryciu, czy "Gruboziarnisty wskaźnik" - Zwykle ekran dotykowy - jest podstawowym urządzeniem wejściowym. W przypadku, gdy chcesz zdekodować, czy urządzenie z np. myszką ma również ekran dotykowy, możesz użyć zamiast tego any-pointer: coarse.

Aby uzyskać więcej informacji, zajrzyj tutaj: wykrywanie, że przeglądarka nie ma myszy i jest tylko dotykowa

 58
Author: Blackbam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-07 14:33:40

Korzystając ze wszystkich powyższych komentarzy zmontowałem następujący kod, który działa na moje potrzeby:

var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));

Przetestowałem to na iPadzie, Androidzie( przeglądarka i Chrome), Blackberry Playbook, iPhone 4s, Windows Phone 8, IE 10, IE 8, IE 10( Windows 8 Z Ekranem Dotykowym), Opera, Chrome i Firefox.

Obecnie nie działa na Windows Phone 7 i nie byłem jeszcze w stanie znaleźć rozwiązania dla tej przeglądarki.

Mam nadzieję, że komuś się to przyda.
 39
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-15 18:36:58

Podoba mi się ten:

function isTouchDevice(){
    return typeof window.ontouchstart !== 'undefined';
}

alert(isTouchDevice());
 21
Author: Benny Neugebauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-16 08:20:25

Jeśli używasz Modernizr , jest bardzo łatwy w użyciu Modernizr.touch, Jak wspomniano wcześniej.

Jednak dla bezpieczeństwa wolę używać kombinacji Modernizr.touch i testów user agent.

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
    }

Jeśli nie korzystasz z Modernizr, możesz po prostu zastąpić powyższą funkcję Modernizr.touch ('ontouchstart' in document.documentElement)

Należy również pamiętać, że testowanie user agent iemobile zapewni szerszy zakres wykrytych urządzeń mobilnych firmy Microsoft niż Windows Phone.

Zobacz też to pytanie

 17
Author: j7my3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:39

Próbowaliśmy implementacji modernizr, ale wykrywanie zdarzeń dotykowych nie jest już spójne (IE 10 mA zdarzenia dotykowe na pulpicie windows, IE 11 działa, ponieważ zostały usunięte zdarzenia dotykowe i dodano API wskaźnika).

Postanowiliśmy więc zoptymalizować stronę jako stronę dotykową, o ile nie wiemy, jaki typ wejścia ma użytkownik. Jest to bardziej niezawodne niż jakiekolwiek inne rozwiązanie.

Nasze badania mówią, że większość użytkowników pulpitu porusza się myszką po ekranie, zanim kliknij, abyśmy mogli je wykryć i zmienić zachowanie, zanim będą mogli kliknąć lub najechać kursorem na cokolwiek.

Jest to uproszczona wersja naszego kodu:

var isTouch = true;
window.addEventListener('mousemove', function mouseMoveDetector() {
    isTouch = false;
    window.removeEventListener('mousemove', mouseMoveDetector);
});
 14
Author: Martin Lantzsch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-04 07:02:18

Jest coś lepszego niż sprawdzanie, czy mają ekran dotykowy, jest sprawdzenie, czy go używają, plus, że jest łatwiej sprawdzić.

if (window.addEventListener) {
    var once = false;
    window.addEventListener('touchstart', function(){
        if (!once) {
            once = true;
            // Do what you need for touch-screens only
        }
    });
}
 9
Author: Ivan Castellanos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-29 01:33:24

Working Fiddle

Udało mi się to osiągnąć w ten sposób;

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

if(isTouchDevice()===true) {
    alert('Touch Device'); //your logic for touch device
}
else {
    alert('Not a Touch Device'); //your logic for non touch device
}
 8
Author: Aamir Shahzad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-26 04:21:43

Ten działa dobrze nawet w tabletach Windows Surface !!!

function detectTouchSupport {
msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture,
touchSupport = (( "ontouchstart" in window ) || msGesture || window.DocumentTouch &&     document instanceof DocumentTouch);
if(touchSupport) {
    $("html").addClass("ci_touch");
}
else {
    $("html").addClass("ci_no_touch");
}
}
 6
Author: Sathiyamoorthy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-10 15:27:04

Użyłem fragmentów powyższego kodu, aby wykryć, czy dotyk, więc moje fancybox iframes pojawi się na komputerach stacjonarnych, a nie na dotyku. Zauważyłem, że Opera Mini dla Androida 4.0 nadal rejestruje się jako urządzenie bezdotykowe, gdy używa samego kodu blmstr. (Czy ktoś wie dlaczego?)

Skończyło się na użyciu:

<script>
$(document).ready(function() {
    var ua = navigator.userAgent;
    function is_touch_device() { 
        try {  
            document.createEvent("TouchEvent");  
            return true;  
        } catch (e) {  
            return false;  
        }  
    }

    if ((is_touch_device()) || ua.match(/(iPhone|iPod|iPad)/) 
    || ua.match(/BlackBerry/) || ua.match(/Android/)) {
        // Touch browser
    } else {
        // Lightbox code
    }
});
</script>
 4
Author: Loved,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-12 20:58:54

Największy "gotcha" z próbami wykrycia dotyku jest na urządzeniach hybrydowych, które obsługują zarówno dotyk, jak i gładzik/mysz. Nawet jeśli jesteś w stanie poprawnie wykryć, czy urządzenie użytkownika obsługuje dotyk, tak naprawdę musisz wykryć, jakiego urządzenia wejściowego używa użytkownik obecnie. Jest szczegółowy opis tego wyzwania i możliwe rozwiązanie tutaj.

Zasadniczo podejście do ustalenia, czy użytkownik dotknął ekranu, czy użył myszy/ trackpad zamiast tego jest rejestrowanie zdarzenia touchstart i mouseover na stronie:

document.addEventListener('touchstart', functionref, false) // on user tap, "touchstart" fires first
document.addEventListener('mouseover', functionref, false) // followed by mouse event, ie: "mouseover"

Akcja dotykowa wywoła oba te zdarzenia, chociaż pierwsze (touchstart) zawsze jest pierwsze na większości urządzeń. Tak więc, licząc na przewidywalną sekwencję zdarzeń, możesz utworzyć mechanizm, który dynamicznie dodaje lub usuwa klasę can-touch do katalogu głównego dokumentu, aby odzwierciedlić bieżący typ wejścia użytkownika w tym momencie w dokumencie:

;(function(){
    var isTouch = false //var to indicate current input type (is touch versus no touch) 
    var isTouchTimer 
    var curRootClass = '' //var indicating current document root class ("can-touch" or "")
     
    function addtouchclass(e){
        clearTimeout(isTouchTimer)
        isTouch = true
        if (curRootClass != 'can-touch'){ //add "can-touch' class if it's not already present
            curRootClass = 'can-touch'
            document.documentElement.classList.add(curRootClass)
        }
        isTouchTimer = setTimeout(function(){isTouch = false}, 500) //maintain "istouch" state for 500ms so removetouchclass doesn't get fired immediately following a touch event
    }
     
    function removetouchclass(e){
        if (!isTouch && curRootClass == 'can-touch'){ //remove 'can-touch' class if not triggered by a touch event and class is present
            isTouch = false
            curRootClass = ''
            document.documentElement.classList.remove('can-touch')
        }
    }
     
    document.addEventListener('touchstart', addtouchclass, false) //this event only gets called when input type is touch
    document.addEventListener('mouseover', removetouchclass, false) //this event gets called when input type is everything from touch to mouse/ trackpad
})();

Więcej Szczegółów tutaj .

 4
Author: coco puffs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-23 20:26:46

Właściwie, zbadałem to pytanie i rozważyłem wszystkie sytuacje. ponieważ jest to duży problem również w moim projekcie. Więc docieram do poniższej funkcji, działa ona dla wszystkich wersji wszystkich przeglądarek na wszystkich urządzeniach:

const isTouchDevice = () => {
  const prefixes = ['', '-webkit-', '-moz-', '-o-', '-ms-', ''];
  const mq = query => window.matchMedia(query).matches;

  if (
    'ontouchstart' in window ||
    (window.DocumentTouch && document instanceof DocumentTouch)
  ) {
    return true;
  }
  return mq(['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join(''));
};

podpowiedź: zdecydowanie, isTouchDevice po prostu zwraca boolean wartości.

 4
Author: AmerllicA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-20 02:20:41

Sprawdź ten post , daje naprawdę ładny fragment kodu, co zrobić, gdy urządzenia dotykowe zostaną wykryte lub co zrobić, jeśli wywołane jest Zdarzenie touchstart:

$(function(){
  if(window.Touch) {
    touch_detect.auto_detected();
  } else {
    document.ontouchstart = touch_detect.surface;
  }
}); // End loaded jQuery
var touch_detect = {
  auto_detected: function(event){
    /* add everything you want to do onLoad here (eg. activating hover controls) */
    alert('this was auto detected');
    activateTouchArea();
  },
  surface: function(event){
    /* add everything you want to do ontouchstart here (eg. drag & drop) - you can fire this in both places */
    alert('this was detected by touching');
    activateTouchArea();
  }
}; // touch_detect
function activateTouchArea(){
  /* make sure our screen doesn't scroll when we move the "touchable area" */
  var element = document.getElementById('element_id');
  element.addEventListener("touchstart", touchStart, false);
}
function touchStart(event) {
  /* modularize preventing the default behavior so we can use it again */
  event.preventDefault();
}
 3
Author: Safran Ali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-22 22:42:45

Unikałbym używania szerokości ekranu do określenia, czy urządzenie jest urządzeniem dotykowym. Istnieją ekrany dotykowe znacznie większe niż 699px, pomyśl o Windows 8. Nawigator.UserAgent może być miły, aby nadpisać fałszywe pozycje.

Polecam sprawdzić ten numer {[4] } na Modernizr.

Czy chcesz sprawdzić, czy urządzenie obsługuje zdarzenia dotykowe lub jest urządzeniem dotykowym. Niestety, to nie to samo.

 3
Author: hybrid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-16 01:47:55

Nie, to niemożliwe. Doskonałe odpowiedzi są zawsze tylko częściowe, ponieważ każda dana metoda będzie produkować fałszywych pozytywów i fałszywych negatywów. Nawet przeglądarka nie zawsze wie, czy ekran dotykowy jest obecny, ze względu na API systemu operacyjnego, a fakt może się zmienić podczas sesji przeglądarki, szczególnie w przypadku rozwiązań typu KVM.

Zobacz więcej szczegółów w tym doskonałym artykule:

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

Artykuł sugeruje rozważasz założenia, które sprawiają, że chcesz wykryć ekrany dotykowe, prawdopodobnie się mylą. (Sprawdziłem własne dla mojej aplikacji, i moje założenia były rzeczywiście błędne!)

Artykuł kończy się:

Dla układów, Załóżmy, że każdy ma ekran dotykowy. Użytkownicy myszy mogą używać duży interfejs użytkownika steruje znacznie łatwiej niż użytkownicy dotykowi mogą korzystać z małych jeden. To samo dotyczy Stanów hover.

W przypadku zdarzeń i interakcji, Załóżmy, że każdy może mieć ekran dotykowy. Wdrożenie klawiatura, mysz i dotyk współdziałają ze sobą, zapewnienie, że nikt nie blokuje się nawzajem.

 3
Author: Dave Burt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-07 23:31:15

Wiele z nich działa, ale albo wymagają jQuery, albo lintery javascript narzekają na składnię. Biorąc pod uwagę, że początkowe pytanie prosi o "JavaScript" (nie jQuery, Nie Modernizr) sposób rozwiązania tego, oto prosta funkcja, która działa za każdym razem. Jest to również tak minimalne, jak można uzyskać.

function isTouchDevice() {
    return !!window.ontouchstart;
}

console.log(isTouchDevice());

Ostatnią korzyścią, o której wspomnę, jest to, że ten kod jest Framework i agnostyczny. Smacznego!

 3
Author: seanforyou23,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-12 03:34:18
var isTouchScreen = 'createTouch' in document;

Lub

var isTouchScreen = 'createTouch' in document || screen.width <= 699 || 
    ua.match(/(iPhone|iPod|iPad)/) || ua.match(/BlackBerry/) || 
    ua.match(/Android/);
Przypuszczam, że byłoby to dokładniejsze sprawdzenie.
 2
Author: samuel segal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-05 03:41:32

Wygląda na to, że Chrome 24 obsługuje teraz zdarzenia dotykowe, prawdopodobnie Dla Windows 8. Więc zamieszczony tutaj kod nie działa. Zamiast próbować wykryć, czy dotyk jest obsługiwany przez przeglądarkę, teraz wiążę zarówno zdarzenia dotyku, jak i kliknięcia i upewniam się, że tylko jedno jest wywołane:

myCustomBind = function(controlName, callback) {

  $(controlName).bind('touchend click', function(e) {
    e.stopPropagation();
    e.preventDefault();

    callback.call();
  });
};

A następnie nazywając go:

myCustomBind('#mnuRealtime', function () { ... });
Mam nadzieję, że to pomoże !
 2
Author: wizmagister,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-01 17:43:28

Wszystkie obsługiwane przeglądarki oprócz Firefox dla pulpitu zawsze TRUE ponieważ Firefox dla pulpitu wsparcie responsywny projekt dla programisty nawet kliknąć przycisk dotykowy lub nie!

Mam nadzieję, że Mozilla naprawi to w następnej wersji.

Używam Firefoksa 28 desktop.

function isTouch()
{
    return !!("ontouchstart" in window) || !!(navigator.msMaxTouchPoints);
}
 2
Author: xicooc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-11 04:26:17

JQuery v1. 11. 3

Jest wiele dobrych informacji w udzielonych odpowiedziach. Ale ostatnio spędziłem dużo czasu próbując połączyć wszystko razem w działające rozwiązanie do osiągnięcia dwóch rzeczy: {]}

  1. Wykryj, że używane urządzenie jest urządzeniem typu ekran dotykowy.
  2. Wykryj, że urządzenie zostało podsłuchane.

Poza tym postem i wykrywaniem urządzeń z Ekranem dotykowym za pomocą Javascript , znalazłem ten post Patricka Lauke niezwykle pomocny: https://hacks.mozilla.org/2013/04/detecting-touch-its-the-why-not-the-how/

Oto kod...
$(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;
    }
});

Ważne! Metoda *.on( events [, selector ] [, data ], handler ) musi mieć selektor, zazwyczaj element, który może obsługiwać zdarzenie "touchstart" lub inne podobne zdarzenie związane z dotknięciami. W tym przypadku jest to element hiperłącza "a".

Teraz nie musisz obsługiwać zwykłego klikania myszką w JavaScript, ponieważ możesz użyć CSS do obsługi tych zdarzeń użycie selektorów dla elementu hiperłącza " a " w ten sposób:

/* unvisited link */
a:link 
{

}

/* visited link */
a:visited 
{

}

/* mouse over link */
a:hover 
{

}

/* selected link */
a:active 
{

}

Uwaga: Istnieją również inne selektory...

 2
Author: serge-k,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:03

Problem

Ze względu na urządzenia hybrydowe, które używają kombinacji wejścia dotykowego i myszy, musisz być w stanie dynamicznie zmienić stan / zmienną, która kontroluje, czy fragment kodu powinien działać, jeśli użytkownik jest użytkownikiem dotykowym, czy nie.

[[5]} urządzenia dotykowe również odpalają mousemove na dotknięcie.

Rozwiązanie

  1. Załóżmy, że dotyk jest fałszywy przy obciążeniu.
  2. poczekaj, aż zostanie wywołane zdarzenie touchstart, a następnie ustaw je na true.
  3. Jeśli touchstart został uruchomiony, dodaj mousemove handler.
  4. Jeśli czas pomiędzy uruchomieniem dwóch zdarzeń mousemove był mniejszy niż 20ms, Załóżmy, że używają myszy jako wejścia. Usuń Zdarzenie, ponieważ nie jest już potrzebne, a mousemove jest kosztownym wydarzeniem dla urządzeń myszy.
  5. gdy tylko touchstart zostanie uruchomiony ponownie (użytkownik wrócił do używania touch), zmienna zostanie ustawiona z powrotem na true. I powtórz proces tak, aby był zdeterminowany w dynamiczny sposób. Jeśli jakimś cudem mousemove odpali dwa razy na dotyk (w moich testach to praktycznie niemożliwe, aby to zrobić w ciągu 20ms), następny touchstart ustawi go z powrotem na true.

Przetestowano na Safari iOS i Chrome dla Androida.

Uwaga: brak 100% pewności na wskaźniku-zdarzenia dla MS Surface, itp.

Codepen demo


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);
}
 2
Author: frosty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Tak więc istnieje ogromna debata na temat wykrywania urządzeń dotykowych / nie-dotykowych. Liczba Tabletów okienkowych i ich wielkość rośnie, co powoduje kolejne bóle głowy dla nas twórców stron internetowych.

Użyłem i przetestowałem odpowiedź blmstr dla menu. Menu działa tak: po załadowaniu strony skrypt wykrywa, czy jest to urządzenie dotykowe, czy nie. Na tej podstawie menu będzie działać po najechaniu kursorem (bez dotyku) lub po kliknięciu/dotknięciu (dotknij).

W większości przypadków blmstr ' s Skrypty wydawały się działać dobrze (konkretnie ten z 2018 roku). Ale nadal było to jedno urządzenie, które zostanie wykryte jako dotyk, gdy nie jest lub odwrotnie.

Z tego powodu trochę poszperałem i dzięki temu artykułowi zamieniłem kilka linijek z 4. skryptu blmstr na to:

function is_touch_device4() {
    if ("ontouchstart" in window)
        return true;

    if (window.DocumentTouch && document instanceof DocumentTouch)
        return true;


    return window.matchMedia( "(pointer: coarse)" ).matches;
}

alert('Is touch device: '+is_touch_device4());
console.log('Is touch device: '+is_touch_device4());

Ze względu na zamknięcie mają ograniczony zapas urządzeń dotykowych do testowania tego, ale do tej pory powyższe działa świetnie.

Ja bym to zrozumiał, gdyby ktoś z pulpitowym urządzeniem dotykowym (np. surface tablet) może potwierdzić, czy skrypt działa dobrze.

Teraz, jeśli chodzi o wsparcie, zapytanie pointer: coarse media wydaje się być obsługiwane. Zatrzymałem linie powyżej, ponieważ miałem (z jakiegoś powodu) problemy na mobilnym Firefoksie, ale linie powyżej zapytania o media robią sztuczkę.

Thanks

 2
Author: Angelosp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-29 10:09:44

Używam:

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

W jQuery mobile 1.0.1

 1
Author: Mark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-19 14:19:34

Zmagałem się również z różnymi opcjami wykrywania w Javascript, czy strona jest wyświetlana na urządzeniu z Ekranem dotykowym, czy nie. IMO, na razie nie istnieje żadna realna opcja, aby prawidłowo wykryć tę opcję. Przeglądarki albo zgłaszają zdarzenia dotykowe na komputerach stacjonarnych (ponieważ system operacyjny może być gotowy na dotyk), albo niektóre rozwiązania nie działają na wszystkich urządzeniach mobilnych.

W końcu zdałem sobie sprawę, że od początku podążałem za złym podejściem: Gdyby moja strona miała wyglądać podobnie na dotyku i urządzenia bezdotykowe, może nie powinienem się martwić o wykrywanie nieruchomości w ogóle: Mój scenariusz polegał na dezaktywacji podpowiedzi nad przyciskami na urządzeniach dotykowych, ponieważ prowadzą one do podwójnych kranów, w których chciałem jednego dotknięcia, aby aktywować przycisk.

Moim rozwiązaniem było refactor widok tak, aby nie było potrzebne podpowiedzi narzędzi nad przyciskiem, a na koniec nie musiałem wykrywać urządzenia dotykowego z Javascript metodami, które wszystkie mają swoje wady .

 1
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-20 09:13:50

Możesz zainstalować modernizer i użyć prostego zdarzenia dotykowego. Jest to bardzo skuteczne i działa na każdym urządzeniu, na którym testowałem, w tym na Windows surface!

I ' ve created a 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
Author: Endjeechner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-01 23:35:27

Praktyczna odpowiedź wydaje się być taka, która uwzględnia kontekst:

1) Public site (no login)
Zakoduj interfejs użytkownika, aby działał z obiema opcjami razem.

2) Login site
Przechwyć, czy ruch myszy wystąpił w formularzu logowania, i zapisz to do ukrytego wejścia. Wartość jest przekazywana wraz z danymi logowania i dodawana do sesji użytkownika , więc może być używana przez czas trwania sesji.

Jquery do dodania do strony logowania tylko:

$('#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 do @ Dave Burt i + 1 do @ Martin lantzsch na ich odpowiedzi)

 1
Author: prograhammer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-09 19:06:14

Myślę, że najlepszą metodą jest:

var isTouchDevice =
    (('ontouchstart' in window) ||
    (navigator.maxTouchPoints > 0) ||
    (navigator.msMaxTouchPoints > 0));
if(!isTouchDevice){
    /* Code for touch device /*
}else{
    /* Code for non touch device */
}
 1
Author: Farhad Sakhaei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-13 06:11:07

Extent jQuery support object:

jQuery.support.touch = 'ontouchend' in document;

A teraz możesz to sprawdzić wszędzie, w ten sposób:

if( jQuery.support.touch )
   // do touch stuff
 0
Author: vsync,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-19 16:50:00