Entender los eventos táctiles

80

Estoy tratando de hacer que algunas de mis bibliotecas funcionen con dispositivos táctiles, pero me cuesta trabajo averiguar cómo son compatibles y cómo funcionan.

Básicamente, hay 5 eventos táctiles , pero parece que hay consenso entre los navegadores móviles solo sobre el touchstartevento (duh). He creado un violín como caso de prueba.

Probé esto en mi Galaxy Note con Android 4 a bordo, pero también puede verificar el enlace con un navegador de escritorio.

El objetivo es tratar de descubrir cómo manejar los grifos, los dobles y largos. Nada sofisticado.

Básicamente, esto es lo que sucede:

El navegador de valores de Android no activa eventos táctiles. Simplemente trata de emular los clics del ratón con grifos, disparando mousedown, mouseupy clickeventos de forma consecutiva, pero los grifos dobles simplemente acercar y alejar tha página.

Chrome para Android dispara el evento de inicio táctil cuando el dedo toca la pantalla. Si es liberado muy pronto, se despide a continuación mousedown, mouseup, touchendy finalmente clickeventos.

En caso de golpe largo , después de aproximadamente medio segundo se dispara mousedowny mouseup, touchendcuando se levanta el dedo, sin ningún clickevento al final.

Si mueve el dedo , dispara un touchmoveevento un par de veces, luego dispara un touchcancelevento y no pasa nada después, ni siquiera un touchendevento al levantar el dedo.

Un doble toque activa las funciones de acercar / alejar, pero en cuanto a los eventos, activa el combo touchstart, toucheventdos veces, sin que se activen los eventos del mouse.

Firefox para Android dispara correctamente el touchstartevento, y en caso de incendios de tomas cortas mousedown, mouseup, touchendy clickdespués.

En caso de mucho toque , dispara mousedown, mouseupy finalmente touchendeventos. Es lo mismo que Chrome para estas cosas.

Pero si mueve el dedo , se dispara touchmovecontinuamente (como es de esperar) pero no dispara el touchleaveevento cuando el dedo deja el elemento con el detector de eventos, y no dispara el touchcancelevento cuando el dedo sale de la ventana del navegador. .

Para toques dobles , se comporta como Chrome.

Opera Mobile hace lo mismo que Chrome y Firefox con un toque corto, pero en caso de una pulsación larga, activa algún tipo de función para compartir que realmente quiero desactivar. Si mueve el dedo o toca dos veces, se comporta como Firefox.

Chrome beta hace lo habitual para toques cortos, pero en caso de toques largos, ya no activa el mouseupevento, solo touchstart, luego de mousedownmedio segundo, luego touchendcuando se levanta el dedo. Cuando se mueve el dedo, ahora se comporta como Firefox y Opera Mobile.

En caso de grifos dobles , que no se dispara eventos de toque cuando el zoom se aleja , pero sólo cuando se hace zoom en.

Chrome beta muestra el comportamiento más extraño, pero realmente no puedo quejarme ya que es una versión beta.

La pregunta es : ¿existe una forma simple y sencilla de intentar detectar toques cortos, toques largos y toques dobles en los navegadores más comunes de dispositivos táctiles?

Lástima que no pueda probarlo en dispositivos iOS con Safari, o IE para Windows Phone 7 / Phone 8 / RT, pero si algunos de ustedes pueden, sus comentarios serán muy apreciados.

MaxArt
fuente
1
¿Has probado Tocca.js? gianlucaguarini.github.io/Tocca.js Permite todos los eventos táctiles que faltan en cualquier tipo de dispositivo y es aproximadamente 1kb
Gianluca Guarini

Respuestas:

26

Si aún no lo ha hecho, le sugiero que lea el código fuente de Hammer.js

https://github.com/hammerjs/hammer.js/blob/master/hammer.js

Entre los comentarios y el código hay unas 1400 líneas, hay una gran documentación y el código es fácil de entender.

Puede ver cómo el autor ha decidido resolver muchos de los eventos táctiles comunes:

sostener, tocar, tocar dos veces, arrastrar, arrastrar, arrancar, arrastrar, arrastrar, arrastrar hacia abajo, arrastrar hacia la izquierda, arrastrar hacia la derecha, deslizar, deslizar hacia arriba, deslizar hacia abajo, deslizar hacia la izquierda, deslizar hacia la derecha, transformar, transformstart, transformar, rotar, pellizcar, pellizcar, pellizcar, tocar (se inicia la detección de gestos) , suelte (finaliza la detección de gestos)

Creo que después de leer el código fuente, comprenderá mucho mejor cómo funcionan los eventos táctiles y cómo identificar qué eventos el navegador es capaz de manejar.

http://eightmedia.github.io/hammer.js/

vrtis
fuente
Un código interesante, parece bastante completo y extenso. Podría tomarme un tiempo analizándolo.
MaxArt
9

Hay un recurso realmente excelente https://patrickhlauke.github.io/touch/tests/results/ que detalla el orden de los eventos en un número asombroso de navegadores. También parece actualizarse periódicamente (en septiembre de 2016, se actualizó por última vez en agosto de 2016).

La esencia es, esencialmente todo lo que desencadena mouseovery los eventos relacionados; la mayoría también desencadenan eventos táctiles, que generalmente se completan (alcanzan touchend) antes mouseovery luego continúan click(a menos que un cambio en el contenido de la página cancele esto). Esas raras excepciones son afortunadamente relativamente raras (navegadores de Android de terceros y libro de jugadas de Blackberry).

Ese recurso vinculado entra en un nivel de detalle impresionante, aquí hay una muestra de las tres primeras de muchas, muchas pruebas de sistema operativo, dispositivo y navegador:

ingrese la descripción de la imagen aquí

Para resumir algunos de los puntos clave:

Navegadores móviles

  • Todos los navegadores enumerados se activan mouseovercon el primer toque. Solo algunos navegadores de Windows Phone lo activan con un segundo toque.
  • Todo disparador click. No especifica qué cancelar clicksi mouseovercambia la página (creo que la mayoría lo hace)
  • La mayoría de los navegadores activan mouseoverdespués de touchstarty touchend. Esto incluye iOS7.1 Safari, Android estándar, Chrome, Opera y Firefox para Android, y algunos (no todos los navegadores de teléfonos con Windows)
  • Varios navegadores de Windows Phone (todos Windows 8 / 8.1 y una versión para 10) y varios navegadores de Android de terceros (Dolphin, Maxathon, UC) activan mouseover después touchstart y touchend.
  • Solo Blackberry Playbook se activa mouseoverentre touchstartytouchend
  • Solo Opera Mini y Puffin (navegador de Android de terceros) carecen de touchstarto touchend.

Navegadores de escritorio

  • Las versiones razonablemente actualizadas de Chrome y Opera de escritorio se comportan como sus contrapartes móviles, touchstarty touchendseguidas de mouseover.
  • Los navegadores Firefox y Microsoft (IE <= 11 y muchas versiones de Edge) no activan ningún evento touchstarty touchend.
  • No hay datos en Mac, pero presumiblemente no son compatibles con los navegadores Ma touchstarty touchenddada la escasez de interfaces de pantalla táctil Mac.

También hay una cantidad increíble de datos en los navegadores combinados con tecnologías de asistencia.

user56reinstatemonica8
fuente
3

Sí, puede iniciar un temporizador en touchstarty finalizarlo touchendy hacer sus elecciones desde allí.

También puede hacer ... digamos deslizar, mi activación touchmovepuede obtener las coordenadas del "dedo" y ver cuánto viajé antes de que touchendse active.

No sé si hay alguna forma más simple en lugar de usar una biblioteca de eventos táctiles, pero supongo que podría escribir una para eventos simples de 'toque', 'doble toque', 'deslizar' con bastante facilidad.

Alexandru Calin
fuente
1
Si lo piensa y considera el comportamiento de los navegadores anteriores, admitirá que no es nada fácil. Por ejemplo, si toca un elemento, luego mueve el dedo fuera del elemento y luego levanta el dedo, ese no sería un "toque" válido, pero no puede detectarlo ya touchleaveque nunca se dispara.
MaxArt
Tienes un buen punto, PERO; con la codificación adecuada, como nosotros, capturando el elemento e.target(creo) en touchstart, ¿es igual al elemento en touchstart? Si no, entonces no es un grifo válido, es una trampa. No estoy diciendo que codificar una biblioteca sea fácil, pero no es realmente "difícil", la clasificaría como "media" + ¿qué es lo divertido si no es un desafío y nos hace regresar a stackoverflow? XD
Alexandru Calin
Codificar una biblioteca no sería un problema para mí, lo encuentro desafiante, satisfactorio y algo divertido. Pero tu comentario solo sugiere una solución, pero ¿cómo la construyes? ¿Dónde guarda la información sobre el touchstartevento? ¿Qué sucede si touchstartmientras tanto se dispara un segundo evento (pantalla multitáctil)? ¿Cómo maneja los grifos largos? Usando setTimeout, pero ¿y si el dedo deja el elemento mientras tanto? ¿Cómo se detecta si no se disparan eventos táctiles? Y así sucesivamente ... Lo intentaré, por supuesto, pero esperaba encontrar un análisis profundo de los eventos táctiles.
MaxArt
No puede disparar un segundo evento de inicio táctil sin que se dispare el evento de toque final, por lo que no puede tener dos toques simultáneos, por lo que no hay problema. Debería mantener la información en las variables y restablecerlas al tocarlas
Alexandru Calin
Eso es incorrecto, puede tener un segundo touchstartantes de que touchendocurra el primero . Además, pensar nuevamente en su respuesta lleva a la conclusión de que no ayudará, porque la targetpropiedad del touchendevento siempre es igual al elemento en el que comenzó el toque, ¡ incluso cuando el dedo se movió fuera del elemento!
MaxArt
3

Aquí está mi última observación sobre eventos táctiles y de mouse en Android 4.3

Opera, Firefox y Chrome parecen tener un comportamiento estándar

  1. Al deslizar (tocar inicio-tocar mover-tocar y):

    1. No se dispara ningún evento de mouse (excepto mouseover).
    2. El mouseover se activa solo si el inicio táctil y el toque final se producen en el mismo elemento. (touchstart-touchmove-touch-mouseover)
    3. Si se evita la opción predeterminada en el inicio táctil: el comportamiento de deslizamiento predeterminado no funciona. no se producen cambios con respecto al disparo del evento del mouse.
  2. Al tocar (toque inicio-toque final):

    1. Todos los eventos del mouse mouseover-mousemove-mousedown-mouseup-click fire after a delay
    2. Si se previene por defecto en el inicio táctil: solo se dispara el mouse sobre el mouse.

El navegador predeterminado de Android tiene algunos comportamientos no estándar :

  1. El mouseover se activa antes de touchstart, lo que significa que el mouseover siempre se activa.
  2. Todos los eventos del mouse se activan al tocar, incluso si se evita el predeterminado en el inicio táctil.
Semra
fuente