Rilevamento di dispositivi touchscreen con Javascript


129

In Javascript / jQuery, come posso rilevare se il dispositivo client ha un mouse?

Ho un sito che fa scorrere un piccolo pannello informativo quando l'utente passa il mouse sopra un oggetto. Sto usando jQuery.hoverIntent per rilevare l'hover, ma questo ovviamente non funziona su dispositivi touchscreen come iPhone / iPad / Android. Quindi su quei dispositivi vorrei tornare a toccare per mostrare il pannello informazioni.


6
Perché non puoi fare entrambe le cose? La funzionalità di tocco è indesiderabile nei dispositivi non touchscreen?
EMPraptor,

1
Poiché alcuni dispositivi più recenti non supportano :hover, è probabilmente meglio (quando si codifica un foglio di stile per più dispositivi) da utilizzare :hovera scopi puramente cosmetici.
Drudge

@empraptor: buon punto - sì, potrei farlo. Tuttavia ... abbiamo anche pensato di mostrare sempre il pannello sui dispositivi touchscreen, nel qual caso avrei bisogno di essere in grado di rilevare il supporto.
Brad Robinson,

Se riesci sempre a mostrare il pannello su dispositivi touchscreen, non puoi mostrarlo anche su altri dispositivi? Quanto è grande il pannello e perché è desiderabile mostrarlo solo al passaggio del mouse / tocco?
EMPraptor,

Risposte:


12

+1 per fare hovered clickentrambi. Un altro modo potrebbe essere l'uso di query multimediali CSS e l'utilizzo di alcuni stili solo per schermi / dispositivi mobili più piccoli, che sono quelli che hanno più probabilità di avere funzionalità touch / tap. Quindi, se hai alcuni stili specifici tramite CSS e da jQuery controlli quegli elementi per le proprietà dello stile del dispositivo mobile, potresti collegarli per scrivere il tuo codice specifico per il cellulare.

Vedi qui: http://www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/


1
Buona soluzione, probabilmente potresti fare qualcosa come un controllo al passaggio del mouse con un one () bind in modo che si attivi solo la prima volta.
Timothy Perez,

Il problema è che se scegli la larghezza dello schermo, quando ruoti il ​​tuo dispositivo (prendiamo iPhone 6+ 736x414) non avrà lo stesso stile. Quindi non la soluzione migliore: /
antoni

266
var isTouchDevice = 'ontouchstart' in document.documentElement;

Nota : solo perché un dispositivo supporta eventi touch non significa necessariamente che sia esclusivamente un dispositivo touch screen. Molti dispositivi (come il mio Asus Zenbook) supportano sia eventi click che touch, anche quando non dispongono di meccanismi di input touch effettivi. Quando si progetta per il supporto touch, includere sempre il supporto eventi click e non dare mai per scontato che qualsiasi dispositivo sia esclusivamente l'uno o l'altro.


33
Come descritto nei documenti di Modernizr, questo rileva solo la capacità del browser , non la capacità del dispositivo ... otterrai un risultato falso positivo su dispositivi senza input touch che eseguono un browser touch. Non conosco un modo per rilevare la funzionalità touch del dispositivo in modo nativo, senza solo aspettare che si verifichi un evento touch.
Stu Cox,

12
Per rilevare anche IE 10 touch sto usando: (window.navigator.msMaxTouchPoints || ('ontouchstart' in document.documentElement));
Alexander Kellett l'

2
'ontouchstart' in document.documentElement restituisce erroneamente true su BlackBerry 9300
Più semplice il

10
@typhon se il software (Win 8, browser moderni) supporta il tocco, questo sarà sempre vero - anche se sei su hardware (desktop, monitor standard, mouse e tastiera) che non supporta il tocco. Pertanto questa soluzione non è aggiornata.
Barney

1
funnyItsNotCamelCaseAsJsIsThroughout. Voglio dire, ora le persone dovranno copiare, incollare E modificare il codice ... :)
Ross,

20

Test trovati per window.Touch non funzionava su Android ma questo fa:

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

Vedi l'articolo: Qual è il modo migliore per rilevare un dispositivo 'touch screen' usando JavaScript?


Questo rileva i touchscreen ma fai attenzione perché restituisce VERO anche per i laptop con touchscreen. Questo potrebbe essere un problema se stai cercando di distinguere se l'utente è da telefono / tablet o computer / laptop perché per i laptop con touchscreen restituisce VERO.
Combina il

8
return (('ontouchstart' in window)
      || (navigator.maxTouchPoints > 0)
      || (navigator.msMaxTouchPoints > 0));

Motivo per l'utilizzo di maxTouchPoints insieme a msMaxTouchPoints:

Microsoft ha dichiarato che a partire da Internet Explorer 11, la versione con prefisso del fornitore Microsoft di questa proprietà (msMaxTouchPoints) potrebbe essere rimossa e consiglia invece di utilizzare maxTouchPoints.

Fonte: http://ctrlq.org/code/19616-detect-touch-screen-javascript


questo ha funzionato e funzionato con strumenti di sviluppo di Google Chrome simulare dispositivo grazie
Behnam Mohammadi

7
if ("ontouchstart" in window || navigator.msMaxTouchPoints) {
    isTouch = true;
} else {
    isTouch = false;
}

Funziona ovunque !!


E cosa c'entra questo con un mouse? (la vera domanda)
hexalys,

Sarebbe più semplice da fareisTouch = "ontouchstart" in window || navigator.msMaxTouchPoints;
Andrew


4

Google Chrome sembra restituire falsi positivi su questo:

var isTouch = 'ontouchstart' in document.documentElement;

Suppongo che abbia qualcosa a che fare con la sua capacità di "emulare eventi tattili" (F12 -> impostazioni nell'angolo in basso a destra -> scheda "sostituzioni" -> ultima casella di controllo). So che è disattivato per impostazione predefinita, ma è a questo che collego la modifica dei risultati (il metodo "in" utilizzato per funzionare in Chrome). Tuttavia, questo sembra funzionare, per quanto ho testato:

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

Tutti i browser su cui ho eseguito quel codice dichiarano che typeof è "oggetto" ma mi sento più sicuro sapendo che è tutt'altro che indefinito :-)

Testato su IE7, IE8, IE9, IE10, Chrome 23.0.1271.64, Chrome per iPad 21.0.1180.80 e iPad Safari. Sarebbe bello se qualcuno eseguisse altri test e condividesse i risultati.


Entrambi i metodi restituiscono falsi positivi su Win 8 PC con FF 23 e Chrome 28. È sempre così o perché una volta avevo un touchscreen collegato a questo computer - probabilmente prima di installare FF e Chrome - ma non più? Non ho impostato l'opzione "emula eventi tocco".
tifone,

Uh, è sempre una lotta con il nuovo hardware. I browser devono lavorare con i livelli di astrazione del sistema operativo ... che non sempre implementano tutto ... in breve, con JS devi fare affidamento sul browser :) Non esiste mai un modo universale.
Ash,

Entrambi tornano veri su Ubuntu Firefox su un laptop non touch.
NoBugs,

4

Ho scritto questo per uno dei miei siti e probabilmente è la soluzione più infallibile. Soprattutto dal momento che anche Modernizr può ottenere falsi positivi sul rilevamento del tocco.

Se stai usando jQuery

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

o semplicemente JS puro ...

window.onmouseover = function(){ 
    window.onmouseover = null;
    document.getElementsByTagName("html")[0].className += " mouse";
}

4
Fai attenzione, però: almeno gli iPad lanciano anche degli avventurieri
Joril

14
Accidenti a te Apple!
Timothy Perez,

E le persone che usano IE su un tablet Windows potrebbero voler usare sia il tocco che il mouse.
Sebazzz,

Questo post è stato pubblicato prima della nascita del Tablet Windows.
Timothy Perez,

@ s427 - Fecking IE ... basta fare un controllo per IE8. Non credo che ci siano dispositivi mobili con <= IE8.
Timothy Perez,

4

Per il mio primo post / commento: sappiamo tutti che il "touchstart" viene attivato prima del clic. Sappiamo anche che quando l'utente apre la tua pagina: 1) sposta il mouse 2) fai clic 3) tocca lo schermo (per scorrere, o ... :))

Proviamo qualcosa:

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

// <- Fine: jQuery

Buona giornata!


3

Ho testato il seguente codice sopra menzionato nella discussione

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

funziona su Android Mozilla, Chrome, Opera, browser predefinito Android e Safari su iPhone ... tutto positivo ...

sembra solido per me :)


Super semplice e funziona bene per me. Testato su Android (vecchio Galaxy Note) e con emulatori (Chrome) e su iPad.
Ralf

Restituisce un falso positivo per me su Chrome.
James,


2

Questo funziona per me:

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

1
su quante piattaforme, browser, sistemi operativi e dispositivi hai testato?
BerggreenDK,

1
FF, Chrome, Safari su Android e iOS (iPad)
Turtletrail

1
Abbastanza carino. Ho appena testato sul desktop e ho ottenuto un sacco di "indefinito" che rende la struttura IF un po 'confusa. Se modifichi leggermente il valore di ritorno, in questo modo: return true == ("ontouchstart" nella finestra || window.DocumentTouch && document instanceof di DocumentTouch); Quindi hai vero o falso :-)
BerggreenDK

2
In Chrome, "ontouchstart" nella finestra è vero sul mio PC senza touchscreen, quindi non funziona. Come notato in precedenza, questo verifica se il browser è abilitato al tocco. Inoltre, true == non fa nulla e deve essere omesso.
rakensi,

1
Quando provo questo in Chrome con l'emulatore integrato, rileverà il tocco quando è acceso nell'emulatore e non rileverà il tocco quando è spento. Quindi funziona bene per me. Ma: io uso la versione breve di Prasad (sotto) che non usa il || nel codice di Turtletrail. E: non mi interessa se funziona per il 100% dei dispositivi. Il 99% lo farà per me.
Ralf

1

Se usi Modernizr , è molto facile da usareModernizr.touch come menzionato in precedenza.

Tuttavia, preferisco utilizzare una combinazione di Modernizr.touchtest utente e utente, solo per sicurezza.

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
    }

Se non usi Modernizr, puoi semplicemente sostituire la Modernizr.touchfunzione sopra con('ontouchstart' in document.documentElement)

Si noti inoltre che il test dell'agente utente iemobileoffre una gamma più ampia di dispositivi mobili Microsoft rilevati rispetto a Windows Phone.

Vedi anche questa domanda SO


2
È la stessa risposta per 4 domande ora ... e questa non è una soluzione per la domanda che sta ponendo.
jycr753,

1
Credo che risponda alla domanda qui
Peter-Pan,

non è la risposta ma è un suggerimento che penso per chi voglia rilevare se il dispositivo è tangibile prima che l'utente lo tocchi
Shahadat Hossain Khan,

1

In jQuery Mobile puoi semplicemente fare:

$.support.touch

Non so perché sia ​​così privo di documenti .. ma è sicuro per i browser (ultime 2 versioni degli attuali browser).


0

Come già accennato, un dispositivo può supportare sia l'input tramite mouse che touch. Molto spesso, la domanda non è "cosa è supportato" ma "cosa viene attualmente utilizzato".

In questo caso, puoi semplicemente registrare gli eventi del mouse (incluso il listener hover) e toccare gli eventi allo stesso modo.

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

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

...

JavaScript dovrebbe chiamare automaticamente il listener corretto in base all'input dell'utente. Quindi, in caso di un evento touch, onTouchStartCallbackverrà generato, emulando il tuo codice al passaggio del mouse.

Nota che un tocco può far scattare entrambi i tipi di ascoltatori, tocco e mouse. Tuttavia, il touch listener inizia per primo e può impedire che i successivi ascoltatori del mouse si attivino chiamando event.preventDefault().

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

Ulteriori letture qui .


-3

Per lo sviluppo di iPad sto usando:

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

Posso quindi collegarmi selettivamente agli eventi basati sul tocco (ad es. Intouchstart) o agli eventi basati sul mouse (ad es. Onmousedown). Non ho ancora testato su Android.


1
Questo non funziona con Opera Mobile 10 o Internet Explorer Mobile 6 (Windows Mobile 6.5).
doubleJ

4
cattivo crossbrowser / cross OS / consigli multipiattaforma.
BerggreenDK,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.