Wykrywanie urządzeń z ekranem dotykowym z Javascriptem

129

W Javascript / jQuery, jak mogę wykryć, czy urządzenie klienckie ma mysz?

Mam witrynę, która przesuwa się w górę małego panelu informacyjnego, gdy użytkownik umieści kursor myszy nad elementem. Używam jQuery.hoverIntent do wykrywania najechania, ale to oczywiście nie działa na urządzeniach z ekranem dotykowym, takich jak iPhone / iPad / Android. Więc na tych urządzeniach chciałbym wrócić do stuknięcia, aby wyświetlić panel informacyjny.

Brad Robinson
źródło
6
Dlaczego nie możesz zrobić obu? Czy funkcja kranu jest niepożądana w urządzeniach bez ekranu dotykowego?
EMPraptor
1
Ponieważ niektóre nowsze urządzenia nie obsługują :hover, prawdopodobnie lepiej (podczas kodowania jednego arkusza stylów dla wielu urządzeń) używać :hoverdo celów czysto kosmetycznych.
drudge
@empraptor: słuszna uwaga - tak, mogę to zrobić. Jednak ... myśleliśmy również o wyświetlaniu panelu zawsze na urządzeniach z ekranem dotykowym - w takim przypadku musiałbym być w stanie wykryć wsparcie.
Brad Robinson,
Jeśli zawsze możesz wyświetlić panel na urządzeniach z ekranem dotykowym, czy nie możesz pokazać go również na innych urządzeniach? Jak duży jest panel i dlaczego warto go wyświetlać tylko po najechaniu kursorem / dotknięciu?
EMPraptor

Odpowiedzi:

12

+1 za robienie hoveri clickjedno i drugie. Innym sposobem może być używanie zapytań o media CSS i używanie niektórych stylów tylko dla mniejszych ekranów / urządzeń mobilnych, które są najbardziej narażone na dotyk / dotknięcie. Więc jeśli masz określone style za pośrednictwem CSS i z jQuery sprawdzasz te elementy pod kątem właściwości stylu urządzenia mobilnego, możesz je podłączyć, aby napisać kod dostosowany do telefonu komórkowego.

Zobacz tutaj: http://www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/

Moin Zaman
źródło
1
Dobre rozwiązanie, prawdopodobnie mógłbyś zrobić coś w rodzaju hover check z one () bind, więc uruchamia się tylko za pierwszym razem.
Timothy Perez
Problem polega na tym, że jeśli celujesz według szerokości ekranu, to po obróceniu urządzenia (weźmy iPhone'a 6+ 736x414) nie będzie miało tego samego stylu. Więc nie jest to najlepsze rozwiązanie: /
antoni
266
var isTouchDevice = 'ontouchstart' in document.documentElement;

Uwaga : fakt, że urządzenie obsługuje zdarzenia dotykowe, nie musi oznaczać, że jest to wyłącznie urządzenie z ekranem dotykowym. Wiele urządzeń (takich jak mój Asus Zenbook) obsługuje zarówno zdarzenia kliknięcia, jak i dotknięcia, nawet jeśli nie mają żadnych rzeczywistych mechanizmów wprowadzania dotykowego. Projektując obsługę dotykową, zawsze uwzględniaj obsługę zdarzenia kliknięcia i nigdy nie zakładaj, że jakiekolwiek urządzenie jest wyłącznie jednym lub drugim.

KevBurnsJr
źródło
33
Jak opisano w dokumentacji Modernizr, wykrywa to tylko możliwości przeglądarki , a nie możliwości urządzenia ... otrzymasz fałszywie dodatni wynik na urządzeniach bez wprowadzania dotykowego z przeglądarką obsługującą dotyk. Nie znam sposobu natywnego wykrywania funkcji dotykowych urządzenia , bez czekania na wystąpienie zdarzenia dotykowego.
Stu Cox
12
Aby również wykryć dotyk IE 10 używam: (window.navigator.msMaxTouchPoints || ('ontouchstart' w document.documentElement));
Alexander Kellett
2
'ontouchstart' in document.documentElement niepoprawnie zwraca prawdę na BlackBerry 9300
Simpler
10
@typhon, jeśli oprogramowanie (Win 8, nowoczesne przeglądarki) obsługuje dotyk, zawsze będzie to prawdą - nawet jeśli używasz sprzętu (komputer stacjonarny, standardowy monitor, mysz i klawiatura), który nie obsługuje dotyku. Dlatego to rozwiązanie jest nieaktualne.
Barney,
1
funnyItsNotCamelCaseAsJsIsThroughout. Mam na myśli, że ludzie będą teraz musieli kopiować, wklejać i edytować kod ... :)
Ross
20

Znaleziono testy dla window.Touch nie działa na Androidzie, ale tak:

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

Zobacz artykuł: Jaki jest najlepszy sposób na wykrycie urządzenia z ekranem dotykowym za pomocą JavaScript?

Hallodom
źródło
To nie wykrywa ekranów dotykowych, ale bądź ostrożny, ponieważ zwraca TRUE również w przypadku laptopów z ekranami dotykowymi. Może to stanowić problem, jeśli próbujesz rozróżnić, czy użytkownik jest z telefonu / tabletu, czy komputera / laptopa, ponieważ w przypadku laptopów z ekranem dotykowym zwraca wartość TRUE.
Połącz
8
return (('ontouchstart' in window)
      || (navigator.maxTouchPoints > 0)
      || (navigator.msMaxTouchPoints > 0));

Powód używania maxTouchPoints wraz z msMaxTouchPoints:

Firma Microsoft oświadczyła, że ​​począwszy od przeglądarki Internet Explorer 11, wersja tej właściwości z prefiksem dostawcy firmy Microsoft (msMaxTouchPoints) może zostać usunięta i zaleca zamiast niej używanie maxTouchPoints.

Źródło: http://ctrlq.org/code/19616-detect-touch-screen-javascript

użytkownik
źródło
to pracował i pracował w google chrome narzędzi programistycznych symulować urządzenie dziękuję
Behnam Mohammadi
7
if ("ontouchstart" in window || navigator.msMaxTouchPoints) {
    isTouch = true;
} else {
    isTouch = false;
}

Działa wszędzie !!

Code Spy
źródło
A co to ma wspólnego z myszą? (właściwe pytanie)
hexalys,
Byłoby prościejisTouch = "ontouchstart" in window || navigator.msMaxTouchPoints;
Andrew
4

Używam:

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

w jQuery mobile 1.0.1

znak
źródło
2
jQuery odradza używanie jQuery.support na rzecz Modernizr ( modernizr.com ): odniesienie - api.jquery.com/jQuery.support -
Jonathan Marzullo
4

Wygląda na to, że Google Chrome zwraca fałszywe alarmy w tym przypadku:

var isTouch = 'ontouchstart' in document.documentElement;

Przypuszczam, że ma to coś wspólnego z możliwością „emulacji zdarzeń dotykowych” (F12 -> ustawienia w prawym dolnym rogu -> zakładka „overrides” -> ostatnie pole wyboru). Wiem, że jest domyślnie wyłączony, ale z tym łączę zmianę w wynikach (metoda „in” używana do pracy w Chrome). Jednak wydaje się, że to działa, o ile przetestowałem:

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

Wszystkie przeglądarki, w których uruchomiłem ten kod w stanie typeof to "object", ale czuję się bardziej pewny, wiedząc, że to nie jest zdefiniowane :-)

Testowano na IE7, IE8, IE9, IE10, Chrome 23.0.1271.64, Chrome na iPada 21.0.1180.80 i iPadzie Safari. Byłoby fajnie, gdyby ktoś zrobił więcej testów i podzielił się wynikami.

Boyan
źródło
Obie metody zwracają fałszywe alarmy na Win 8 PC z FF 23 i Chrome 28. Czy tak jest zawsze, czy też dlatego, że miałem kiedyś ekran dotykowy podłączony do tego komputera - prawdopodobnie przed zainstalowaniem FF i Chrome - ale już nie? Nie mam ustawionej opcji „emuluj zdarzenia dotykowe”.
tyfon
Uh, zawsze jest walka z nowym sprzętem. Przeglądarki muszą pracować z warstwami abstrakcji systemu operacyjnego… które nie zawsze implementują wszystko… w skrócie, w przypadku JS musisz polegać na przeglądarce :) Nigdy nie ma uniwersalnego sposobu.
Boyan
Oba zwracają prawdę w Ubuntu Firefox na laptopie bez obsługi dotykowej.
NoBugs
4

Napisałem to dla jednej z moich witryn i prawdopodobnie jest to najbardziej niezawodne rozwiązanie. Zwłaszcza, że ​​nawet Modernizr może uzyskać fałszywe alarmy po wykryciu dotyku.

Jeśli używasz jQuery

$(window).one({
  mouseover : function(){
    Modernizr.touch = false; // Add this line if you have Modernizr
    $('html').removeClass('touch').addClass('mouse');
  } 
});

lub po prostu czysty JS ...

window.onmouseover = function(){ 
    window.onmouseover = null;
    document.getElementsByTagName("html")[0].className += " mouse";
}
Timothy Perez
źródło
4
Uważaj jednak: przynajmniej iPady też rzucają onmouseovers
Joril
14
Cholera Apple!
Timothy Perez
A ludzie używający IE na tablecie z Windows mogą chcieć używać zarówno dotyku, jak i myszy.
Sebazzz
Ten post powstał przed powstaniem tabletu z systemem Windows.
Timothy Perez
@ s427 - Fecking IE ... po prostu sprawdź, czy jest IE8. Myślę, że nie ma żadnych urządzeń mobilnych z <= IE8.
Timothy Perez
4

Mój pierwszy post / komentarz: Wszyscy wiemy, że „touchstart” jest uruchamiany przed kliknięciem. Wiemy również, że gdy użytkownik otworzy Twoją stronę, będzie: 1) poruszał myszą 2) klikał 3) dotykał ekranu (przewijanie, lub ... :))

Spróbujmy czegoś:

// -> Start: 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';
});

// <- End: jQuery

Miłego dnia!

silassare
źródło
3

Przetestowałem następujący kod wymieniony powyżej w dyskusji

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

działa na Androidzie Mozilla, Chrome, Opera, domyślnej przeglądarce Androida i Safari na iPhonie ... wszystko pozytywne ...

wydaje mi się solidne :)

Prasad
źródło
Super proste i działa dobrze dla mnie. Przetestowano na Androidzie (stary Galaxy Note), emulatorach (Chrome) i na iPadzie.
Ralf
Zwraca mi fałszywy alarm w przeglądarce Chrome.
James
2

To działa dla mnie:

function isTouchDevice(){
    return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}
Turtletrail
źródło
1
na ilu platformach, przeglądarkach, systemach operacyjnych, urządzeniach testowałeś?
BerggreenDK
1
FF, Chrome, Safari na Androida i iOS (iPad)
Turtletrail,
1
Wystarczająco miło. Właśnie przetestowałem na komputerze stacjonarnym i otrzymałem wiele „niezdefiniowanych”, co sprawia, że ​​struktura IF jest nieco zepsuta. Jeśli trochę skorygujesz zwracaną wartość, na przykład: return true == ("ontouchstart" w oknie || window.DocumentTouch && instancja dokumentu DocumentTouch); Wtedy masz prawdę lub fałsz :-)
BerggreenDK
2
W przeglądarce Chrome „ontouchstart” w oknie działa na moim komputerze bez ekranu dotykowego, więc to nie działa. Jak wspomniano wcześniej, test ten sprawdza, czy przeglądarka obsługuje dotyk. Ponadto true == nic nie robi i należy je pominąć.
rakensi
1
Kiedy spróbuję tego w Chrome z wbudowanym emulatorem, wykryje dotyk, gdy jest włączony w emulatorze, i nie wykryje dotyku, gdy jest wyłączony. Więc działa dobrze dla mnie. Ale: używam skróconej wersji Prasada (poniżej), która nie używa || w kodzie Turtletrail. I: Nie obchodzi mnie, czy działa na 100% urządzeń. 99% wystarczy.
Ralf
1

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

Jednak wolę używać kombinacji Modernizr.touchtestów agenta użytkownika, aby być bezpiecznym.

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 używasz Modernizr, możesz po prostu zamienić Modernizr.touchpowyższą funkcję na('ontouchstart' in document.documentElement)

Pamiętaj również, że testowanie klienta użytkownika iemobilezapewni szerszy zakres wykrytych urządzeń mobilnych Microsoft niż Windows Phone.

Zobacz także to pytanie SO

Piotruś Pan
źródło
2
To ta sama odpowiedź na 4 pytania teraz ... i to nie jest odpowiedź na pytanie, które zadaje.
jycr753
1
Wierzę, że to odpowiada na pytanie tutaj
Piotruś Pan
to nie jest odpowiedź, ale myślę, że jest to wskazówka dla kogo, kto chce wykryć, czy urządzenie jest dotykalne, zanim użytkownik go dotknie
Shahadat Hossain Khan
1

W jQuery Mobile możesz po prostu:

$.support.touch

Nie wiem, dlaczego jest to tak nieudokumentowane… ale jest bezpieczne dla wielu przeglądarek (ostatnie 2 wersje obecnych przeglądarek).

OZZIE
źródło
0

Jak już wspomniano, urządzenie może obsługiwać zarówno mysz, jak i dotyk. Bardzo często pytanie nie brzmi „co jest obsługiwane”, ale „co jest aktualnie używane”.

W tym przypadku możesz po prostu zarejestrować zdarzenia myszy (w tym nasłuchiwanie po najechaniu kursorem) i podobnie zdarzenia dotknąć.

element.addEventListener('touchstart',onTouchStartCallback,false);

element.addEventListener('onmousedown',onMouseDownCallback,false);

...

JavaScript powinien automatycznie wywołać właściwy odbiornik na podstawie danych wprowadzonych przez użytkownika. Tak więc w przypadku zdarzenia dotykowegoonTouchStartCallback zostanie , emulując kod najechania.

Zwróć uwagę, że dotknięcie może odpalić oba rodzaje słuchaczy, dotyk i mysz. Jednak słuchacz dotyku przechodzi pierwszy i może uniemożliwić kolejnym słuchaczom myszy wywołanie event.preventDefault().

function onTouchStartCallback(ev) {
    // Call preventDefault() to prevent any further handling
    ev.preventDefault();
    your code...
}

Dalsze czytanie tutaj .

user3792852
źródło
-3

Do tworzenia iPada używam:

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

Mogę wtedy selektywnie łączyć się ze zdarzeniami dotykowymi (np. Ontouchstart) lub zdarzeniami opartymi na myszy (np. Onmousedown). Nie testowałem jeszcze na Androidzie.

Zatrzymać się
źródło
1
To nie działa z Opera Mobile 10 lub Internet Explorer Mobile 6 (Windows Mobile 6.5).
podwójneJ
4
złe porady dotyczące różnych przeglądarek / systemów operacyjnych / platform.
BerggreenDK