Detectar dispositivos de pantalla táctil con Javascript

129

En Javascript / jQuery, ¿cómo puedo detectar si el dispositivo cliente tiene un mouse?

Tengo un sitio que se desliza hacia arriba en un pequeño panel de información cuando el usuario pasa el mouse sobre un elemento. Estoy usando jQuery.hoverIntent para detectar el desplazamiento, pero esto obviamente no funciona en dispositivos con pantalla táctil como iPhone / iPad / Android. Entonces, en esos dispositivos, me gustaría volver a tocar para mostrar el panel de información.

Brad Robinson
fuente
66
¿Por qué no puedes hacer las dos cosas? ¿Es la funcionalidad de tap indeseable en dispositivos sin pantalla táctil?
EMPraptor
1
Dado que algunos dispositivos más nuevos no son compatibles :hover, probablemente sea mejor (al codificar una hoja de estilo para varios dispositivos) usar con :hoverfines puramente cosméticos.
drudge
@empraptor: buen punto, sí, podría hacer eso. Sin embargo ... también estábamos pensando en mostrar siempre el panel en dispositivos con pantalla táctil, en cuyo caso necesitaría poder detectar el soporte.
Brad Robinson
Si siempre puede mostrar el panel en dispositivos con pantalla táctil, ¿no podría mostrarlo también en otros dispositivos? ¿Qué tan grande es el panel y por qué es deseable mostrarlo solo al pasar el mouse / tocar?
EMPraptor

Respuestas:

12

+1 por hacer hovery clickambas cosas. Otra forma podría ser usar consultas de medios CSS y usar algunos estilos solo para pantallas / dispositivos móviles más pequeños, que son los que tienen más probabilidades de tener funcionalidad táctil / táctil. Entonces, si tiene algunos estilos específicos a través de CSS, y desde jQuery verifica esos elementos para las propiedades de estilo del dispositivo móvil, puede engancharlos para escribir su código específico para dispositivos móviles.

Ver aquí: http://www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/

Moin Zaman
fuente
1
Buena solución, probablemente podría hacer algo como una comprobación de desplazamiento con un enlace one () para que solo se active la primera vez.
Timothy Perez
El problema es que si apunta por el ancho de la pantalla, cuando gire su dispositivo (tomemos el iPhone 6+ 736x414) no tendrá el mismo estilo. Así que no es la mejor solución: /
antoni
266
var isTouchDevice = 'ontouchstart' in document.documentElement;

Nota : el hecho de que un dispositivo admita eventos táctiles no significa necesariamente que sea exclusivamente un dispositivo de pantalla táctil. Muchos dispositivos (como mi Asus Zenbook) admiten eventos de clic y toque, incluso cuando no tienen ningún mecanismo de entrada táctil real. Cuando diseñe para soporte táctil, siempre incluya soporte para eventos de clic y nunca asuma que cualquier dispositivo es exclusivamente uno u otro.

KevBurnsJr
fuente
33
Como se describe en los documentos de Modernizr, esto solo detecta la capacidad del navegador , no la capacidad del dispositivo ... obtendrá un resultado falso positivo en dispositivos sin entrada táctil que ejecutan un navegador con capacidad táctil. No conozco una forma de detectar la capacidad táctil del dispositivo de forma nativa, sin solo esperar a que ocurra un evento táctil.
Stu Cox
12
Para detectar también IE 10 touch, estoy usando: (window.navigator.msMaxTouchPoints || ('ontouchstart' en document.documentElement));
Alexander Kellett
2
'ontouchstart' in document.documentElement devuelve incorrectamente verdadero en BlackBerry 9300
Más simple
10
@typhon si el software (Win 8, navegadores modernos) admite el tacto, esto siempre será cierto, incluso si está en un hardware (escritorio, monitor estándar, mouse y teclado) que no admite el tacto. Por lo tanto, esta solución está desactualizada.
Barney
1
funnyItsNotCamelCaseAsJsIsThroughout. Quiero decir que la gente ahora tendrá que copiar, pegar Y editar el código ... :)
Ross
20

Se encontraron pruebas para window.Touch no funcionaba en Android, pero esto sí:

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

Ver artículo: ¿Cuál es la mejor manera de detectar un dispositivo de 'pantalla táctil' usando JavaScript?

hallodom
fuente
Esto detecta pantallas táctiles, pero tenga cuidado porque devuelve VERDADERO para las computadoras portátiles con pantallas táctiles también. Esto podría ser un problema si está tratando de distinguir si el usuario es de teléfono / tableta O computadora / computadora portátil porque para computadoras portátiles con pantalla táctil devuelve VERDADERO.
Combine el
8
return (('ontouchstart' in window)
      || (navigator.maxTouchPoints > 0)
      || (navigator.msMaxTouchPoints > 0));

Motivo para usar maxTouchPoints junto con msMaxTouchPoints:

Microsoft ha declarado que a partir de Internet Explorer 11, la versión prefijada por el proveedor de Microsoft de esta propiedad (msMaxTouchPoints) puede eliminarse y recomienda utilizar maxTouchPoints en su lugar.

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

usuario
fuente
esto funcionó y funcionó en las herramientas de desarrollo de Google Chrome simular dispositivo gracias
Behnam Mohammadi
7
if ("ontouchstart" in window || navigator.msMaxTouchPoints) {
    isTouch = true;
} else {
    isTouch = false;
}

Funciona en todas partes!

Code Spy
fuente
¿Y qué tiene eso que ver con un mouse? (la pregunta real)
hexalys 01 de
Sería más simple hacerloisTouch = "ontouchstart" in window || navigator.msMaxTouchPoints;
Andrew
4

Yo suelo:

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

en jQuery mobile 1.0.1

marca
fuente
2
jQuery recomienda no usar jQuery.support a favor de Modernizr ( modernizr.com ): referencia - api.jquery.com/jQuery.support -
Jonathan Marzullo
4

Google Chrome parece devolver falsos positivos en este caso:

var isTouch = 'ontouchstart' in document.documentElement;

Supongo que tiene algo que ver con su capacidad de "emular eventos táctiles" (F12 -> configuración en la esquina inferior derecha -> pestaña "anular" -> última casilla de verificación). Sé que está desactivado de manera predeterminada, pero eso es con lo que conecto el cambio en los resultados (el método "in" solía funcionar en Chrome). Sin embargo, esto parece estar funcionando, por lo que he probado:

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

Todos los navegadores en los que he ejecutado ese código indican que typeof es "objeto", pero estoy más seguro sabiendo que es cualquier cosa menos indefinida :-)

Probado en IE7, IE8, IE9, IE10, Chrome 23.0.1271.64, Chrome para iPad 21.0.1180.80 y iPad Safari. Sería genial si alguien hiciera algunas pruebas más y compartiera los resultados.

Ceniza
fuente
Ambos métodos arrojan falsos positivos en PC Win 8 con FF 23 y Chrome 28. ¿Es este siempre el caso o es porque una vez tuve una pantalla táctil conectada a esta computadora, probablemente antes de instalar FF y Chrome, pero ya no? No tengo la opción "emular eventos táctiles" establecida.
tifón
Uh, siempre es una lucha con el nuevo hardware. Los navegadores tienen que trabajar con las capas de abstracción del sistema operativo ... que no siempre implementan todo ... en resumen, con JS tienes que confiar en el navegador :) Nunca hay una forma universal.
Ash
Ambos se vuelven verdaderos en Ubuntu Firefox en una computadora portátil no táctil.
NoBugs
4

Escribí esto para uno de mis sitios y probablemente sea la solución más infalible. Sobre todo porque incluso Modernizr puede obtener falsos positivos en la detección táctil.

Si estás usando jQuery

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

o simplemente JS puro ...

window.onmouseover = function(){ 
    window.onmouseover = null;
    document.getElementsByTagName("html")[0].className += " mouse";
}
Timothy Perez
fuente
44
Sin embargo, tenga cuidado: al menos los iPads también se
colocan
14
¡Maldita sea Apple!
Timothy Perez
Y las personas que usan IE en una tableta de Windows pueden querer usar tanto el tacto como el mouse.
Sebazzz el
Esta publicación se realizó antes de que Windows Tablet surgiera.
Timothy Perez el
@ s427 - Fecking IE ... simplemente verifique IE8. No creo que haya dispositivos móviles con <= IE8.
Timothy Perez
4

Para mi primera publicación / comentario: Todos sabemos que 'touchstart' se activa antes de hacer clic. También sabemos que cuando el usuario abra su página, él o ella: 1) moverá el mouse 2) hará clic en 3) tocará la pantalla (para desplazarse, o ... :))

Probemos algo:

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

// <- Fin: jQuery

¡Que tengas un buen día!

silassare
fuente
3

He probado el siguiente código mencionado anteriormente en la discusión

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

funciona en Android Mozilla, Chrome, Opera, navegador predeterminado de Android y Safari en iPhone ... todo positivo ...

me parece sólido :)

Prasad
fuente
Súper simple y funciona bien para mí. Probado en Android (antiguo Galaxy Note) y con emuladores (Chrome) y en iPad.
Ralf
Devuelve un falso positivo para mí en Chrome.
James
2

Esto funciona para mi:

function isTouchDevice(){
    return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}
Turtletrail
fuente
1
¿en cuántas plataformas, navegador, sistema operativo y dispositivos has probado?
BerggreenDK
1
FF, Chrome, Safari en Android e iOS (iPad)
Turtletrail
1
Lo suficientemente agradable. Acabo de probar en el escritorio y obtuve muchos "indefinidos", lo que hace que la estructura IF sea un poco confusa. Si ajusta su valor de retorno solo un poco, así: return true == ("ontouchstart" en window || window.DocumentTouch && document instanceof DocumentTouch); Entonces tienes verdadero o falso :-)
BerggreenDK
2
En Chrome, "ontouchstart" en la ventana es cierto en mi PC sin una pantalla táctil, por lo que esto no funciona. Como se señaló anteriormente, esto prueba si el navegador tiene capacidad táctil. Además, true == no hace nada y debe omitirse.
rakensi
1
Cuando pruebo esto en Chrome con el emulador incorporado, detectará el tacto cuando esté encendido en el emulador, y no detectará el tacto cuando esté apagado. Entonces funciona bien para mí. Pero: uso la versión corta de Prasad (abajo) que no usa el || en el código de Turtletrail. Y: no me importa si funciona para el 100% de los dispositivos. El 99% lo hará por mí.
Ralf
1

Si usa Modernizr , es muy fácil de usar Modernizr.touchcomo se mencionó anteriormente.

Sin embargo, prefiero usar una combinación de Modernizr.touchpruebas de agente de usuario, solo para estar seguro.

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
    }

Si no usa Modernizr, simplemente puede reemplazar la Modernizr.touchfunción anterior con('ontouchstart' in document.documentElement)

También tenga en cuenta que probar el agente de usuario iemobilele dará una gama más amplia de dispositivos móviles de Microsoft detectados que Windows Phone.

También vea esta pregunta SO

Peter Pan
fuente
2
Es la misma respuesta para 4 preguntas ahora ... y esta no es una solución para la pregunta que hace.
jycr753
1
Creo que aquí responde la pregunta
Peter-Pan
no es la respuesta, pero es una pista, creo, para quién quiere detectar si el dispositivo es táctil antes de que el usuario lo toque
Shahadat Hossain Khan
1

En jQuery Mobile simplemente puede hacer:

$.support.touch

No sé por qué esto es tan indocumentado ... pero es seguro para los navegadores cruzados (las últimas 2 versiones de los navegadores actuales).

OZZIE
fuente
0

Como ya se mencionó, un dispositivo puede admitir tanto el mouse como la entrada táctil. Muy a menudo, la pregunta no es "qué se admite" sino "qué se utiliza actualmente".

Para este caso, simplemente puede registrar eventos del mouse (incluido el oyente de desplazamiento) y tocar eventos por igual.

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

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

...

JavaScript debería llamar automáticamente al oyente correcto según la entrada del usuario. Por lo tanto, en caso de un evento táctil, onTouchStartCallbackse disparará, emulando su código de desplazamiento.

Tenga en cuenta que un toque puede disparar ambos tipos de oyentes, toque y mouse. Sin embargo, el oyente táctil va primero y puede evitar que los siguientes oyentes del mouse disparen llamando event.preventDefault().

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

Lectura adicional aquí .

usuario3792852
fuente
-3

Para el desarrollo de iPad estoy usando:

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

Entonces puedo vincularme selectivamente a los eventos basados ​​en el tacto (por ejemplo, ontouchstart) o eventos basados ​​en el mouse (por ejemplo, onmousedown). Todavía no lo he probado en Android.

Halton
fuente
1
Esto no funciona con Opera Mobile 10 o Internet Explorer Mobile 6 (Windows Mobile 6.5).
doubleJ
44
mal consejo de crossbrowser / cross OS / cross platform.
BerggreenDK