Tocco e mouse

Insieme di nuovo per la prima volta

Introduzione

Per quasi trent'anni, le esperienze di utilizzo dei computer desktop si sono concentrate su una tastiera e un mouse o un trackpad come dispositivi di input principali per gli utenti. Negli ultimi dieci anni, però, smartphone e tablet hanno introdotto un nuovo paradigma di interazione: il tocco. Con l'introduzione dei computer Windows 8 con tocco e ora con il rilascio del fantastico Chromebook Pixel con tocco, il tocco sta diventando parte dell'esperienza desktop prevista. Una delle maggiori sfide è creare esperienze che funzionino non solo su dispositivi touch e con mouse, ma anche su questi dispositivi in cui l'utente utilizzerà entrambi i metodi di input, a volte contemporaneamente.

Questo articolo ti aiuterà a capire come le funzionalità touch sono integrate nel browser, come puoi integrare questo nuovo meccanismo di interfaccia nelle tue app esistenti e come il tocco può funzionare bene con l'input del mouse.

Lo stato del contatto nella piattaforma web

L'iPhone è stata la prima piattaforma popolare ad avere API touch dedicate integrate nel browser web. Diversi altri fornitori di browser hanno creato interfacce API simili progettate per essere compatibili con l'implementazione di iOS, ora descritta dalla specifica "Touch Events versione 1". Gli eventi tocco sono supportati da Chrome e Firefox sui computer desktop, da Safari su iOS e Chrome e dal browser Android su Android, nonché da altri browser per dispositivi mobili come il browser BlackBerry.

Il mio collega Boris Smus ha scritto un ottimo tutorial di HTML5Rocks sugli eventi tocco che è ancora un buon modo per iniziare se non hai mai esaminato gli eventi tocco. Infatti, se non hai mai lavorato con gli eventi tocco, leggi l'articolo prima di continuare. Vai, ti aspetto.

Hai finito? Ora che hai una conoscenza di base degli eventi tocco, la difficoltà di scrivere interazioni con il tocco è che queste possono essere molto diverse dagli eventi del mouse (e del trackpad e della trackball che simulano il mouse). Sebbene le interfacce touch in genere cerchino di emulare i mouse, questa emulazione non è perfetta o completa. Devi quindi utilizzare entrambi gli stili di interazione e potresti dover supportare ogni interfaccia in modo indipendente.

L'aspetto più importante: l'utente potrebbe avere un tocco e un mouse

Molti sviluppatori hanno creato siti che rilevano in modo statico se un ambiente supporta gli eventi tocco e poi presumono di dover supportare solo gli eventi tocco (e non del mouse). Questa è un'ipotesi errata: il fatto che siano presenti eventi touch non significa che l'utente utilizzi principalmente il dispositivo di input touch. Dispositivi come Chromebook Pixel e alcuni laptop Windows 8 ora supporteranno ENTRAMBI i metodi di immissione tramite mouse e tocco e altri metodi lo saranno nel prossimo futuro. Su questi dispositivi, è abbastanza naturale per gli utenti utilizzare sia il mouse sia il touchscreen per interagire con le applicazioni, quindi "supporta il tocco" non è sinonimo di "non richiede il supporto del mouse". Non si può pensare al problema come "Devo scrivere due stili di interazione diversi e passare da uno all'altro", bisogna pensare a come le due interazioni interagiranno e come interagiranno in modo indipendente. Sul mio Chromebook Pixel uso spesso il trackpad, ma tocco anche lo schermo e nella stessa applicazione o pagina faccio ciò che mi sembra più naturale in quel momento. D'altra parte, alcuni utenti di laptop con touchscreen non lo useranno mai o quasi mai, quindi la presenza di input tocco non deve disattivare o ostacolare il controllo del mouse.

Sfortunatamente, può essere difficile sapere se l'ambiente del browser di un utente supporta o meno l'input touch; idealmente, un browser su un computer desktop indicherà sempre il supporto per gli eventi touch, quindi è possibile collegare un display touchscreen in qualsiasi momento (ad esempio, se diventa disponibile un touchscreen collegato tramite un KVM). Per tutti questi motivi, le tue applicazioni non devono tentare di passare dal tocco al mouse, ma supportare entrambi.

Supporto del mouse e del tocco contemporaneamente

1. Clic e tocco: l'ordine "naturale" delle cose

Il primo problema è che le interfacce touch in genere cercano di emulare i clic del mouse, ovviamente, poiché le interfacce touch devono funzionare su applicazioni che hanno interagito solo con eventi del mouse in precedenza. Puoi utilizzarla come scorciatoia, perché gli eventi di "clic" continueranno a essere attivati, indipendentemente dal fatto che l'utente abbia fatto clic con il mouse o abbia toccato il dito sullo schermo. Tuttavia, ci sono un paio di problemi con questa scorciatoia.

Innanzitutto, devi fare attenzione quando progetti interazioni touch più avanzate: quando l'utente utilizza un mouse, la risposta avviene tramite un evento di clic, ma quando tocca lo schermo si verificano sia eventi di tocco che di clic. Per un singolo clic, l'ordine degli eventi è:

  1. touchstart
  2. touchmove
  3. touchend
  4. mouseover
  5. mousemove
  6. mousedown
  7. Mouse-up
  8. clic

Questo, ovviamente, significa che se stai elaborando eventi touch come touchstart, devi assicurarti di non elaborare anche l'evento di mousedown e/o clic corrispondente. Se puoi annullare gli eventi touch (chiamare preventDefault() all'interno del gestore di eventi), non verranno generati eventi relativi al mouse per il tocco. Una delle regole più importanti degli handler tocco è:

Tuttavia, questo impedisce anche altri comportamenti predefiniti del browser (come lo scorrimento), anche se in genere gestisci l'evento tocco interamente nel gestore e vuoi disattivare le azioni predefinite. In genere, è consigliabile gestire e annullare tutti gli eventi tocco oppure evitare di avere un gestore per questo evento.

In secondo luogo, quando un utente tocca un elemento in una pagina web su un dispositivo mobile, le pagine che non sono state progettate per l'interazione mobile hanno un ritardo di almeno 300 millisecondi tra l'evento touchstart e l'elaborazione degli eventi del mouse (mousedown). Puoi farlo utilizzando Chrome. Puoi attivare l'opzione "Emulare eventi tocco" negli Strumenti per sviluppatori di Chrome per testare le interfacce touch su un sistema non touch.

Questo ritardo consente al browser di determinare se l'utente sta eseguendo un altro gesto, in particolare lo zoom con doppio tocco. Ovviamente, questo può essere problematico nei casi in cui si voglia avere una risposta istantanea al tocco di un dito. Sono in corso dei lavori per cercare di limitare gli scenari in cui si verifica automaticamente questo ritardo.

Chrome per Android Browser Android Opera Mobile per Android) Firefox per Android Safari per iOS
Area visibile non scalabile Nessun ritardo 300 ms 300 ms Nessun ritardo 300 ms
Nessuna area visibile 300 ms 300 ms 300 ms 300 ms 300 ms

Il primo e più semplice modo per evitare questo ritardo è "comunicare" al browser mobile che la pagina non avrà bisogno di zoom, operazione che può essere eseguita utilizzando un'area visibile fissa, ad esempio inserendo nella pagina:

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

Naturalmente, questa opzione non è sempre appropriata, perché disattiva lo zoom con due dita, che potrebbe essere necessario per motivi di accessibilità, quindi utilizzala con parsimonia, se non del tutto (se disattivi la scalabilità dell'utente, ti consigliamo di fornire un altro modo per aumentare la leggibilità del testo nella tua applicazione). Inoltre, questo ritardo non si applica a Chrome sui dispositivi di classe desktop che supportano il tocco e ad altri browser su piattaforme mobile quando la pagina ha viewport non scalabili.

#2: gli eventi Mousemove non vengono attivati dal tocco

A questo punto è importante notare che l'emulazione degli eventi del mouse in un'interfaccia touch in genere non si estende all'emulazione degli eventi mousemove. Pertanto, se crei un bel controllo basato sul mouse che utilizza gli eventi mousemove, probabilmente non funzionerà con un dispositivo touch, a meno che non aggiungi anche gestori touchmove specifici.

In genere, i browser implementano automaticamente l'interazione appropriata per le interazioni touch sui controlli HTML. Ad esempio, i controlli di intervallo HTML5 funzioneranno solo quando utilizzi le interazioni touch. Tuttavia, se hai implementato i tuoi controlli, probabilmente non funzioneranno con le interazioni di tipo clic e trascinamento. Infatti, alcune librerie di uso comune (come jQueryUI) non supportano ancora in modo nativo le interazioni touch in questo modo (anche se per jQueryUI esistono diversi fix di monkey-patch per questo problema). Questo è stato uno dei primi problemi che ho riscontrato durante l'upgrade dell'applicazione Web Audio Playground per il funzionamento con il tocco: i cursori erano basati su jQueryUI, quindi non funzionavano con le interazioni di trascinamento e clic. Ho eseguito la transizione ai controlli intervallo HTML5 e funzionano. In alternativa, avrei potuto semplicemente aggiungere gestori touchmove per aggiornare i cursori, ma c'è un problema…

#3: Touchmove e MouseMove non sono la stessa cosa

Un errore che ho visto commettere da alcuni sviluppatori è quello di chiamare gli handler touchmove e mousemove negli stessi percorsi di codice. Il comportamento di questi eventi è molto simile, ma leggermente diverso: in particolare, gli eventi tocco hanno sempre come target l'elemento in cui è iniziato il tocco, mentre gli eventi del mouse hanno come target l'elemento attualmente sotto il cursore del mouse. Questo è il motivo per cui abbiamo gli eventi mouseover e mouseout, ma non esistono eventi touchover e touchout corrispondenti, solo touchend.

Il modo più comune in cui questo può accadere è se rimuovi (o sposti) l'elemento che l'utente ha iniziato a toccare. Ad esempio, immagina un carosello di immagini con un gestore tocco sull'intero carosello per supportare il comportamento di scorrimento personalizzato. Man mano che le immagini disponibili cambiano, rimuovi alcuni elementi <img> e ne aggiungi altri. Se l'utente inizia a toccare una di queste immagini e poi la rimuovi, il gestore (che si trova in un antenato dell'elemento img) smetterà di ricevere eventi tocco (poiché vengono inviati a un target che non è più nell'albero). Sembrerà che l'utente tenga il dito in un punto anche se potrebbe averlo spostato e alla fine averlo rimosso.

Ovviamente, puoi evitare questo problema evitando di rimuovere elementi che hanno (o hanno antenati che hanno) gestori di tocco mentre è attivo un tocco. In alternativa, la soluzione migliore è, anziché registrare gestori statici di touchend/touchmove, attendere di ricevere un evento touchstart e poi aggiungere gestori di touchmove/touchend/touchcancel al target dell'evento touchstart (e rimuoverli su end/cancel). In questo modo continuerai a ricevere eventi per il tocco anche se l'elemento di destinazione viene spostato/rimosso. Puoi eseguire questa operazione un po' qui: tocca la casella rossa e, mentre tieni premuto premi Esc per rimuoverla dal DOM.

#4: tocco ed effetto hover

La metafora del cursore del mouse ha separato la posizione del cursore dalla selezione attiva, consentendo agli sviluppatori di utilizzare gli stati di passaggio del mouse per nascondere e mostrare informazioni che potrebbero essere pertinenti per gli utenti. Tuttavia, la maggior parte delle interfacce tattili in questo momento non rileva un dito che "passa il mouse" sopra un obiettivo, quindi fornire informazioni semanticamente importanti (ad esempio fornire il popup "Qual è questo controllo?") in base al passaggio del mouse è un no, a meno che tu non fornisca anche un modo touch-friendly per accedere a queste informazioni. Devi fare attenzione a come utilizzi il passaggio del mouse per trasmettere informazioni agli utenti.

È interessante notare, però, che in alcuni casi la pseudoclasse CSS :hover PUÒ essere attivata dalle interfacce touch: toccare un elemento lo rende :active mentre il dito è premuto e acquisisce anche lo stato :hover. Con Internet Explorer, il passaggio del mouse sopra viene attivato solo quando il dito dell'utente è abbassato, mentre gli altri browser mantengono attivo il passaggio del mouse fino al successivo tocco o spostamento del mouse. Questo è un buon approccio per far funzionare i menu popup sulle interfacce touch. Un effetto collaterale dell'attivazione di un elemento è che viene applicato anche lo stato :hover. Ad esempio:

<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 volta toccato un altro elemento, questo non è più attivo e lo stato di passaggio del mouse scompare, proprio come se l'utente stesse utilizzando il cursore del mouse e lo avesse spostato dall'elemento. Ti consigliamo di racchiudere i contenuti in un elemento <a> per renderli anche un punto di tabulazione. In questo modo, l'utente può attivare/disattivare le informazioni aggiuntive passando il mouse sopra o facendo clic, toccando o premendo un tasto, senza bisogno di JavaScript. Sono rimasto piacevolmente sorpreso quando ho iniziato a lavorare per far funzionare bene il mio Web Audio Playground con le interfacce touch che i miei menu popup funzionavano già bene sul tocco, perché avevo utilizzato questo tipo di struttura.

Il metodo riportato sopra funziona bene per le interfacce basate sul puntatore del mouse e per le interfacce touch. Ciò è in contrasto con l'uso degli attributi "title" al passaggio del mouse, che NON verranno visualizzati quando l'elemento viene attivato:

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

N. 5: precisione del tocco e del mouse

Sebbene i mouse non siano concettualmente associati alla realtà, risultano essere estremamente precisi, in quanto il sistema operativo sottostante monitora generalmente la precisione esatta dei pixel per il cursore. Gli sviluppatori di app mobile, invece, hanno imparato che i tocchi con le dita su un touch screen non sono altrettanto precisi, soprattutto a causa delle dimensioni della superficie del dito quando è a contatto con lo schermo (e in parte perché le dita ostruiscono lo schermo).

Molti individui e aziende hanno condotto ricerche approfondite sugli utenti su come progettare applicazioni e siti che consentano l'interazione basata sulle dita e molti libri sono stati scritti sull'argomento. Il consiglio di base è aumentare le dimensioni dei target di tocco aumentando il padding e ridurre la probabilità di tocchi errati aumentando il margine tra gli elementi. I margini non sono inclusi nella gestione del rilevamento dei hit degli eventi di tocco e clic, mentre lo è il padding. Una delle correzioni principali che ho dovuto apportare al Web Audio Playground è stata l'aumento delle dimensioni dei punti di connessione in modo da poterli toccare con maggiore facilità.

Molti fornitori di browser che gestiscono interfacce basate sul tocco hanno anche introdotto nel browser una logica per aiutare a scegliere come target l'elemento corretto quando un utente tocca lo schermo e ridurre la probabilità di clic errati, anche se in genere vengono corretti solo gli eventi di clic, non i movimenti (anche se sembra che Internet Explorer modifichi anche gli eventi mousedown/mousemove/mouseup).

#6: mantieni contenuti i gestori tocco, altrimenti la visualizzazione scorrerà a scatti

Inoltre, è importante che i gestori del tocco siano limitati solo agli elementi in cui sono necessari; gli elementi touch possono avere una larghezza di banda molto elevata, quindi è importante evitare i gestori del tocco sugli elementi che scorrono (in quanto la tua elaborazione può interferire con le ottimizzazioni del browser per lo scorrimento tattile veloce senza scaglioni: i browser moderni cercano di scorrere su un thread GPU, ma questo è impossibile se devono prima controllare con JavaScript per vedere se ogni evento tocco verrà gestito dall'app). Puoi consultare un esempio di questo comportamento.

Una linea guida da seguire per evitare questo problema è assicurarti che, se gestisci gli eventi tocco solo in una piccola parte dell'interfaccia utente, colleghi i gestori tocco solo lì (ad es. non nel <body> della pagina); in breve, limita il più possibile l'ambito dei gestori tocco.

#7: Multi-touch

L'ultima sfida interessante è che, anche se la chiamiamo interfaccia utente "Touch", quasi universalmente il supporto è in realtà per il multi-touch, ovvero le API forniscono più di un input tocco alla volta. Quando inizi a supportare il tocco nelle tue applicazioni, devi considerare in che modo più tocchi potrebbero influire sulla tua applicazione.

Se hai creato app principalmente basate sul mouse, sei abituato a creare usando al massimo un punto del cursore: i sistemi in genere non supportano più cursori del mouse. Per molte applicazioni, è sufficiente mappare gli eventi touch su un'unica interfaccia con il cursore, ma la maggior parte dell'hardware che abbiamo individuato per l'input tocco desktop è in grado di gestire almeno due ingressi simultanei e la maggior parte del nuovo hardware sembra supportare almeno 5 ingressi simultanei. Per sviluppare una tastiera di pianoforte sullo schermo, ovviamente, devi essere in grado di supportare più input tocco simultanei.

Le API W3C Touch attualmente implementate non hanno un'API per determinare il numero di punti di contatto supportati dall'hardware, quindi dovrai utilizzare la tua stima migliore del numero di punti di contatto che i tuoi utenti vorranno oppure, ovviamente, prestare attenzione al numero di punti di contatto che vedi in pratica e adattarti. Ad esempio, in un'applicazione per pianoforte, se non vedi mai più di due punti di contatto, ti consigliamo di aggiungere un'interfaccia utente "accordi". L'API PointerEvents ha un'API per determinare le funzionalità del dispositivo.

Ritocco

Ci auguriamo che questo articolo ti abbia fornito alcune indicazioni sulle sfide comuni nell'implementazione del tocco insieme alle interazioni con il mouse. Più importante di qualsiasi altro consiglio, ovviamente, è che devi testare la tua app su dispositivi mobili, tablet ed ambienti desktop combinati con mouse e tocco. Se non hai hardware touch e mouse, utilizza l'opzione "Emulare eventi tocco" di Chrome per testare i diversi scenari.

Non solo è possibile, ma è relativamente facile seguire queste indicazioni, creare esperienze interattive coinvolgenti che funzionano bene con input tocco, input del mouse e persino entrambi gli stili di interazione contemporaneamente.