Modo táctil y mouse

Juntos de nuevo por primera vez

Introducción

Durante casi treinta años, las experiencias informáticas de escritorio se han centrado en un teclado y un mouse o panel táctil como nuestros principales dispositivos de entrada del usuario. No obstante, en la última década, los teléfonos inteligentes y las tabletas incorporaron un nuevo paradigma de interacción: el tacto. Con la introducción de las máquinas táctiles con Windows 8 y, con el lanzamiento de la increíble Chromebook Pixel, con pantalla táctil, la tecnología táctil se vuelve parte de la experiencia de escritorio esperada. Uno de los mayores desafíos es crear experiencias que funcionen no solo en dispositivos táctiles y mouses, sino también en estos dispositivos en los que el usuario usará ambos métodos de entrada, a veces simultáneamente.

Este artículo te ayudará a comprender cómo se integran las capacidades táctiles en el navegador, cómo puedes integrar este nuevo mecanismo de interfaz en tus apps existentes y cómo el tacto puede jugar correctamente con la entrada del mouse.

El estado del contacto en la plataforma web

El iPhone fue la primera plataforma popular con APIs táctiles dedicadas integradas en el navegador web. Varios otros proveedores de navegadores crearon interfaces de API similares que fueron compatibles con la implementación de iOS, que ahora se describe en la especificación"Eventos táctiles versión 1". Los eventos táctiles son compatibles con Chrome y Firefox en computadoras de escritorio, y con Safari en iOS y Chrome y con el navegador de Android en Android, al igual que con otros navegadores para dispositivos móviles, como Blackberry.

Mi colega Boris Smus escribió un excelente instructivo de HTML5Rocks sobre los eventos táctiles que sigue siendo una buena manera de comenzar si es la primera vez que consultas los eventos táctiles. De hecho, si es la primera vez que trabajas con eventos táctiles, lee ese artículo ahora, antes de continuar. Vamos, esperaré.

¿Terminaste? Ahora que tienes una base básica en los eventos táctiles, el desafío de escribir interacciones táctiles es que las interacciones táctiles pueden ser bastante diferentes de los eventos del mouse (y del panel táctil que emulan el mouse y la bola de seguimiento) y, aunque las interfaces táctiles suelen intentar emular los mouses, esa emulación no es perfecta ni completa; realmente debes trabajar a través de ambos estilos de interacción y es posible que debas admitir cada interfaz de forma independiente.

Lo más importante: el usuario puede tener contacto y un mouse

Muchos desarrolladores crearon sitios que detectan de forma estática si un entorno admite eventos táctiles y, luego, asumen que solo necesitan admitir eventos táctiles (y no del mouse). Esta suposición es errónea y, en cambio, el hecho de que haya eventos táctiles no significa que el usuario esté usando principalmente ese dispositivo de entrada táctil. Los dispositivos como la Chromebook Pixel y algunas laptops con Windows 8 ahora admiten métodos de entrada táctil y de mouse, y otros lo serán en un futuro cercano. En estos dispositivos, es bastante natural que los usuarios usen tanto el mouse como la pantalla táctil para interactuar con las aplicaciones, por lo que "admite el tacto" no es lo mismo que "no necesita compatibilidad con un mouse". No puedes pensar en el problema como "tengo que escribir dos estilos de interacción diferentes y alternar entre ellos", debes pensar en cómo ambas interacciones funcionarán en conjunto, así como de forma independiente. En mi Chromebook Pixel, uso el panel táctil con frecuencia, pero también levanto la mano y toco la pantalla: en la misma aplicación o página, hago lo que se sienta más natural en este momento. Por otro lado, algunos usuarios de laptops con pantalla táctil rara vez usarán la pantalla táctil, por lo que la presencia de entrada táctil no debería inhabilitar ni obstaculizar el control del mouse.

Lamentablemente, puede ser difícil saber si el entorno del navegador de un usuario admite o no la entrada táctil. Lo ideal sería que un navegador de una computadora de escritorio siempre indique que es compatible con eventos táctiles, de modo que se pueda conectar una pantalla táctil en cualquier momento (por ejemplo, si está disponible una pantalla táctil conectada a través de un KVM). Por todas estas razones, tus aplicaciones no deberían intentar alternar entre la función táctil y el mouse, solo admiten ambas.

Compatibilidad con el mouse y el tacto juntos

N.o 1 - Hacer clic y presionar: el orden "natural" de las cosas

El primer problema es que las interfaces táctiles suelen intentar emular los clics del mouse; obviamente, ya que las interfaces táctiles deben funcionar en aplicaciones que antes solo interactuaron con eventos del mouse. Puedes usarlo como un acceso directo, ya que se seguirán activando los eventos de "clic", ya sea que el usuario haya hecho clic con el mouse o haya presionado el dedo en la pantalla. Sin embargo, este acceso directo presenta algunos problemas.

Primero, debes tener cuidado cuando diseñes interacciones táctiles más avanzadas: cuando el usuario use un mouse, este responderá con un evento de clic, pero, cuando toque la pantalla, ocurrirán tanto eventos táctiles como de clic. Para un solo clic, el orden de los eventos es el siguiente:

  1. inicio táctil
  2. movimiento táctil
  3. punto de contacto
  4. desplazar el mouse sobre un anuncios
  5. mousemove
  6. mousedown
  7. mouseup
  8. click

Esto, por supuesto, significa que si estás procesando eventos táctiles como touchstart, debes asegurarte de no procesar también el evento de clic o mousedown correspondiente. Si puedes cancelar los eventos táctiles (llama a preventDefault() dentro del controlador de eventos), no se generarán eventos del mouse para el toque. La siguiente es una de las reglas más importantes de los controladores táctiles:

Sin embargo, esto también evita otros comportamientos predeterminados del navegador (como el desplazamiento), aunque normalmente estás manejando el evento táctil por completo en tu controlador y QUIERES inhabilitar las acciones predeterminadas. En general, se recomienda controlar y cancelar todos los eventos táctiles o evitar tener un controlador para ese evento.

En segundo lugar, cuando un usuario toca un elemento de una página web en un dispositivo móvil, las páginas que no se diseñaron para interacción móvil tienen un retraso de al menos 300 milisegundos entre el evento touchstart y el procesamiento de los eventos del mouse (mousedown). Esto se puede hacer usando Chrome. Puedes activar "Emular eventos táctiles" en las Herramientas para desarrolladores de Chrome para probar interfaces táctiles en un sistema no táctil.

Esta demora permite que el navegador determine si el usuario está realizando otro gesto, en particular, presionar dos veces el zoom. Evidentemente, esto puede ser un problema en los casos en los que deseas obtener una respuesta instantánea al tocar con el dedo. Hay trabajo en curso para tratar de limitar las situaciones en las que este retraso ocurre automáticamente.

Chrome para Android Navegador de Android Opera Mobile para Android) Firefox para Android Safari en iOS
Ventana gráfica no escalable Sin retraso 300 ms 300 ms Sin retraso 300 ms
Sin viewport 300 ms 300 ms 300 ms 300 ms 300 ms

La primera forma de evitar este retraso, y la más sencilla, es "indicarle" al navegador móvil que la página no necesitará zoom. Para ello, puedes usar una viewport fija, p. ej., mediante la inserción en tu página:

<meta name="viewport" content="width=device-width,user-scalable=no">

Esto no siempre es apropiado, por supuesto, ya que inhabilita el pellizcar para acercar, lo que puede ser necesario por razones de accesibilidad, así que úsalo con moderación si lo deseas (si inhabilitas el ajuste de escala de los usuarios, es posible que desees proporcionar alguna otra manera de aumentar la legibilidad del texto en tu aplicación). Además, en el caso de Chrome para dispositivos de escritorio compatibles con la pantalla táctil y otros navegadores en plataformas móviles cuando la página tiene viewports no escalables, esta demora no se aplica.

2: Los eventos Mousemove no se activan por tacto

Es importante tener en cuenta que, en este punto, la emulación de eventos del mouse en una interfaz táctil, por lo general, no se extiende a la emulación de eventos mousemove; por lo tanto, si creas un hermoso control basado en mouse que usa eventos mousemove, es probable que no funcione con un dispositivo táctil, a menos que también agregues específicamente controladores touchmove.

Los navegadores suelen implementar automáticamente la interacción apropiada para las interacciones táctiles en los controles HTML. Por lo tanto, por ejemplo, los controles de rango HTML5 solo funcionan cuando utilizas interacciones táctiles. Sin embargo, si implementaste tus propios controles, es probable que no funcionen en las interacciones de hacer clic y arrastrar. De hecho, algunas bibliotecas de uso general (como jQueryUI) aún no admiten interacciones táctiles de forma nativa de esta manera (aunque para jQueryUI, existen varias correcciones de monkey-patch para este problema). Este fue uno de los primeros problemas que tuve cuando actualicé mi aplicación Web Audio Playground para que funcione con los controles táctiles. Los controles deslizantes se basaban en jQueryUI, por lo que no funcionaban con las interacciones de hacer clic y arrastrar. Cambié a los controles de rango HTML5 y funcionó. Como alternativa, por supuesto, podría haber agregado controladores touchmove para actualizar los controles deslizantes, pero hay un problema con eso...

N.o 3: Touchmove y MouseMove no son lo mismo

Algunos desarrolladores cometen errores cuando hacen llamadas a los controladores touchmove y mousemove en las mismas rutas de código. El comportamiento de estos eventos es muy parecido, pero levemente diferente. En particular, los eventos táctiles siempre se orientan al elemento donde se COMENZÓ, mientras que los eventos del mouse se orientan al elemento que se encuentra actualmente debajo del cursor del mouse. Es por eso que tenemos eventos de desplazamiento del mouse sobre el anuncio y desplazamiento del mouse, pero no hay eventos de touchover y de salida correspondientes, solo de touchend.

La forma más común en la que esto puede afectarte es si quitas (o reubicas) el elemento que el usuario comenzó a tocar. Por ejemplo, imagina un carrusel de imágenes con un controlador táctil en todo el carrusel para admitir el comportamiento de desplazamiento personalizado. A medida que cambien las imágenes disponibles, quitarás algunos elementos <img> y agregarás otros. Si el usuario comienza a tocar una de esas imágenes y luego la quitas, tu controlador (que está en un elemento principal del elemento img) dejará de recibir eventos táctiles (porque se envían a un objetivo que ya no está en el árbol). Parece que el usuario sostiene el dedo en un solo lugar, aunque lo haya movido y, al final, lo haya quitado.

Por supuesto, puedes evitar este problema si evitas quitar elementos que tengan controladores táctiles (o que tengan principales que los tengan) mientras un toque está activo. Como alternativa, la mejor guía es, en lugar de registrar controladores estáticos de touchend/touchmove, esperar hasta que recibas un evento de touchmove y, luego, agregar controladores touchmove/touchend/touchcancel al target del evento touchstart (y quitarlos al finalizar o cancelar). De esta manera, seguirás recibiendo eventos del toque, incluso si se mueve o quita el elemento objetivo. Puedes jugar con esto aquí. Toca el cuadro rojo y, mientras presionas Escape, presiona Escape para quitarlo del DOM.

N.o 4: Tocar y colocar el cursor sobre un elemento

La metáfora del puntero del mouse separaba la posición del cursor de la selección activa, lo que permitió a los desarrolladores usar los estados de desplazamiento para ocultar y mostrar información que podría ser pertinente para los usuarios. Sin embargo, en la actualidad, la mayoría de las interfaces táctiles no detectan un dedo que se “desplace” sobre un objetivo, por lo que proporcionar información semánticamente importante (p.ej., una ventana emergente de “¿qué es este control?”) basada en el desplazamiento del cursor es un no, a menos que también ofrezcas una forma táctil para acceder a esta información. Debes tener cuidado con la forma en que usas el desplazamiento del mouse para retransmitir información a los usuarios.

Sin embargo, curiosamente, la pseudoclase CSS :hover de CSS puede activarse a través de interfaces táctiles en algunos casos. Presionar un elemento hace que se :active mientras el dedo está hacia abajo, y también adquiere el estado :hover. (Con Internet Explorer, el desplazamiento del cursor solo se activa cuando el dedo del usuario está hacia abajo; los demás navegadores mantienen el cursor activado hasta que se presiona o se mueve el mouse). Este es un buen enfoque para lograr que los menús emergentes funcionen en interfaces táctiles. Un efecto secundario al activar un elemento es que también se aplica el estado :hover. Por ejemplo:

<style>
img ~ .content {
  display:none;
}

img:hover ~ .content {
  display:block;
}
</style>

<img src="/awesome.png">
<div class="content">This is an awesome picture of me</div>

Una vez que se presiona otro elemento, este deja de estar activo y el estado de desplazamiento desaparece, como si el usuario usara el puntero del mouse y lo quitara del elemento. Es posible que desees unir el contenido a un elemento <a> para que también se convierta en una tabulación. De esta manera, el usuario puede activar o desactivar la información adicional con el desplazamiento del mouse o un clic, una presión táctil o una tecla, sin necesidad de JavaScript. Me sorprendí gratamente cuando empecé a trabajar para hacer que mi Web Audio Playground funcionara bien con interfaces táctiles que mis menús emergentes ya funcionaban bien al tacto, porque había usado este tipo de estructura.

El método anterior funciona bien para las interfaces basadas en el puntero del mouse, así como para las interfaces táctiles. Esto contrasta con el uso de atributos de "título" cuando se coloca el cursor sobre ellos, que NO se mostrarán cuando se active el elemento:

<img src="/awesome.png" title="this doesn't show up in touch">

N. o 5: Precisión táctil frente a precisión del mouse

Si bien los mouses tienen una separación conceptual de la realidad, resulta que son extremadamente precisos, ya que el sistema operativo subyacente generalmente realiza un seguimiento de la precisión de píxeles exactos para el cursor. Por otro lado, los desarrolladores para dispositivos móviles aprendieron que los toques de los dedos en una pantalla táctil no son tan precisos, principalmente debido al tamaño del área de superficie del dedo cuando está en contacto con la pantalla (y en parte porque estos dedos obstruyen la pantalla).

Muchas personas y empresas han realizado investigaciones exhaustivas sobre usuarios sobre cómo diseñar aplicaciones y sitios que se adapten a la interacción basada en dedos, y se han escrito muchos libros sobre el tema. El consejo básico es aumentar el tamaño de los objetivos táctiles aumentando el relleno y disminuir la probabilidad de toques incorrectos aumentando el margen entre los elementos. (Los márgenes no se incluyen en el control de detección de hits de eventos táctiles y de clic, mientras que el padding sí). Una de las principales correcciones que tuve que hacer en Web Audio Playground fue aumentar el tamaño de los puntos de conexión para que fueran más precisos para tocarlos con mayor precisión.

Muchos proveedores de navegadores que manejan interfaces táctiles también han incorporado lógica al navegador para ayudar a orientar el elemento correcto cuando un usuario toca la pantalla y reducir la probabilidad de clics incorrectos, aunque esto generalmente solo corrige los eventos de clic, no los movimientos (aunque Internet Explorer también parece modificar los eventos mousedown/mousemove/mouseup).

N.o 6: No olvides los controladores táctiles para evitar que se bloquee el desplazamiento

También es importante mantener los controladores táctiles confinados solo a los elementos donde los necesitas; los elementos táctiles pueden tener un ancho de banda muy alto, por lo que es importante evitar controladores táctiles en los elementos de desplazamiento (ya que tu procesamiento puede interferir con las optimizaciones del navegador para un desplazamiento táctil rápido sin bloqueos. Los navegadores modernos intentan desplazarse en un subproceso de GPU, pero esto es imposible si primero tienen que verificar con JavaScript si la app controlará cada evento táctil). Consulta un ejemplo de este comportamiento.

Una orientación que debes seguir para evitar este problema es asegurarte de que, si solo controlas eventos táctiles en una pequeña parte de tu IU, solo adjuntarás controladores táctiles allí (no, p. ej., en el <body> de la página). En resumen, limita el alcance de los controladores táctiles tanto como sea posible.

N.o 7: Multitoque

El último desafío interesante es que, aunque nos referimos a ella como interfaz de usuario "táctil", casi en todo el mundo la compatibilidad es en realidad para la función multitáctil, es decir, las APIs proporcionan más de una entrada táctil a la vez. Cuando comiences a admitir las acciones táctiles en tus aplicaciones, debes considerar cómo múltiples toques podrían afectar tu aplicación.

Si has creado apps principalmente accionadas por un mouse, entonces estás acostumbrado a compilar con, como máximo, un punto del cursor; los sistemas generalmente no admiten varios cursores de mouse. En muchas aplicaciones, solo se asignarán eventos táctiles a una sola interfaz de cursor; sin embargo, la mayor parte del hardware que vimos para la entrada táctil de escritorio puede manejar al menos 2 entradas simultáneas, y la mayoría del hardware nuevo parece admitir al menos 5 entradas simultáneas. Para desarrollar un teclado de piano en pantalla, por supuesto, debes poder admitir varias entradas táctiles simultáneas.

Las W3C Touch APIs actualmente implementadas no tienen una API para determinar cuántos puntos de contacto admite el hardware, por lo que tendrás que usar tu mejor estimación sobre la cantidad de puntos de contacto que tus usuarios querrán o, por supuesto, prestar atención a cuántos puntos táctiles verás en la práctica y adaptarte. Por ejemplo, en una aplicación de piano, si nunca ves más de dos puntos táctiles, es posible que desees agregar algunas IU de "cords". La API de PointerEvents tiene una API para determinar las capacidades del dispositivo.

Retoque

Esperamos que este artículo te haya brindado orientación sobre los desafíos comunes de la implementación del modo táctil junto con las interacciones del mouse. Más importante que cualquier otro consejo, por supuesto, es que debas probar tu aplicación en dispositivos móviles, tabletas y entornos combinados de escritorio táctil y mouse. Si no tienes hardware de pantalla táctil + mouse, usa la opción "Emular eventos táctiles" de Chrome para probar diferentes situaciones.

No solo es posible seguir estas guías, sino que es relativamente sencillo crear experiencias interactivas atractivas que funcionen bien con la entrada táctil, la entrada del mouse y hasta ambos estilos de interacción al mismo tiempo.