Touchy.js è una libreria che ci consente di aggiungere il supporto "touch" alle pagine HTML per renderle più adatte ai dispositivi naturalmente abilitati a questo tipo di interazione come tablet e smartphone.
Per raggiungere questo scopo esistono diverse soluzioni. Ad esempio, l'API Pointer Events fornisce il supporto a qualsiasi dispositivo di puntamento e tocco e ci aiuta a gestire "gesture" complesse. Si tratta però di uno standard in via di definizione, e non supportati appieno da tutti i browser. Inoltre può risultare eccessivo ricorrere ad uno strumento così potente se le funzionalità da implementare sono tutto sommato semplici.
Touchy.js in questi casi può risultare conveniente: semplifica, non appesantisca inutilmente la pagina, non introduce voluminose dipendenze e funziona sulla maggior parte dei browser in uso.
Primi passi con Touchy.js
Iniziamo con lo scaricare Touchy.js da GitHub. Possiamo anche scegliere di contribuire al progetto usando il proprio client Git preferito.
Per utilizzarla nella pagina HTML, è sufficiente includere il riferimento allo script "touchy.js
":
<script src="js/touchy.js"></script>
Vediamo ora come configurarla per intercettare gli eventi legati al tocco che ci interessano.
Inizializzazione della libreria
Il primo passo da fare è definire l'elemento della pagina su cui l'utente potrà interagire con le dita; ad esempio, possiamo predisporre un elemento <div>
:
Attribuendogli dimensioni sufficientemente grandi:
#touch-me {
z-index: 1;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
... e ottenere il riferimento all'oggetto corrispondente del DOM:
var touchMe = document.getElementById("touch-me");
Lo step successivo è quello di attivare la ricezione degli eventi scatenati dal tocco dell'utente sul nostro div.
La libreria fornisce un oggetto globale, denominato guardacaso Touchy
, che consente di inizializzare il sistema e avviare l'ascolto degli eventi.
Ecco un esempio della chiamata più semplice:
var toucher = Touchy(touchMe, function (hand, finger) {
// ...qui il codice di gestione degli eventi...
});
La funzione accetta come parametro l'oggetto del DOM che deve essere monitorato (nel nostro caso, il DIV con identificativo #touchMe
, a cui faremo riferimento in tutti gli esempi) e una funzione di callback che viene richiamata quando vi sono eventi da gestire.
Alla callback vengono passati due oggetti che contengono informazioni sull'interazione dell'utente:
Argomento | Descrizione |
---|---|
finger | contiene informazioni sul percorso tracciato da un singolo dito sullo schermo, dal momento in cui viene appoggiato fino al suo sollevamento; |
hand | contiene informazioni sulle dita della mano dell'utente che stanno interagendo con lo schermo. |
L'oggetto restituito (memorizzato nella variabile toucher
, nel nostro caso) consente di interagire con il motore dopo la sua inizializzazione. Ad esempio:
- il metodo
.stop()
consente di interrompere la gestione del tocco; .start()
riabilita la gestione del tocco.
Gestione degli eventi base
La logica applicativa dovrà essere inserita all'interno della funzione di callback passata all'oggetto Touchy
, utilizzando opportunamente i parametri finger
e hand
in base ai casi d'uso.
Ad esempio, possiamo escludere l'uso di più dita contemporaneamente controllandone il numero:
if (hand.fingers.length > 1) {
return;
}
Esistono soluzioni più congeniali per stabilire il numero di dita supportate: le vedremo in seguito.
La proprietà fingers del parametro hand
è un array di elementi (dello stesso tipo del parametro finger
) che contengono le informazioni relative ai percorsi tracciati da una o più dita; nell'esempio stiamo verificando che non venga posato più di un singolo dito sullo schermo.
Se vogliamo intervenire nei momenti chiave in cui l'utente appoggia il dito sullo schermo, quindi lo trascina e infine lo rilascia, possiamo agganciare apposite routine agli eventi supportati dall'oggetto passato nel parametro finger
.
Nell'esempio che segue, rileviamo il punto in cui ha inizio il tocco gestendo l'evento start:
// Questa funzione viene chiamata quando
// l'utente appoggia inizialmente il dito sullo schermo
finger.on('start', function (point) {
// ...qui il codice di gestione dell’evento...
});
Quando il dito si trova sullo schermo, ogni trascinamento scatena l'evento move:
// Questa funzione viene chiamata quando
// l'utente trascina il dito sullo schermo
finger.on('move', function (point) {
// ... qui il codice di gestione dell’evento ...
});
Quando il dito viene sollevato, l'azione si interrompe e l'evento end viene generato:
// Questa funzione viene chiamata quando
// l’utente solleva il dito dallo schermo
finger.on('end', function (point) {
// ...qui il codice di gestione dell’evento...
});
Il parametro point passato a tutte le funzioni di callback contiene informazioni sul punto in cui agisce il tocco, quali
Campo | Descrizione |
---|---|
id | È l'identificativo univoco associato al dito (finger) |
x, y | Sono le coordinate del punto toccato, trascinato o rilasciato |
time | Il momento (timestamp) in cui è avvenuta la rilevazione |
Queste informazioni riferite all'ultimo punto toccato sono disponibili nella proprietà lastPoint dell'oggetto finger
.
Come visto, il metodo on() consente di agganciare le funzioni di callback agli eventi; essi possono essere "sganciati" con il metodo off() o eseguiti una volta sola con once(); inoltre, è possibile simulare artificialmente qualsiasi evento con il metodo trigger(), in modo del tutto simile a quanto avviene in altri noti framework JavaScript, come JQuery:
Touchy(touchMe, function (hand, finger) {
function fingerHandler() {
// ...qui la gestione del dito...
}
finger.on('start', fingerHandler); // Aggancia la funzione all’evento "start"
finger.off('start', fingerHandler); // Sgancia la funzione dall’evento "start"
finger.once('start', fingerHandler); // Esegue la funzione per un solo evento "start"
finger.trigger('start', arg1, ..); // Simula l’evento "start" e forza la sua gestione
});
Il "multi touch"
Gli esempi visti sino a ora consentono di gestire un numero imprecisato di dita appoggiate simultaneamente sullo schermo in modo del tutto generico; esistono tuttavia situazioni in cui si vuole amministrare l'uso di un determinato numero di dita che agiscono simultaneamente sullo schermo, concentrando in distinte funzioni di callback le parti di codice che rispondono a una specifica "gesture".
Ecco un esempio di costrutto:
Touchy(touchMe, {
one: function (hand, finger) {
// ... gestire qui le interazioni di un singolo dito sullo schermo...
},
two: function (hand, finger1, finger2) {
// ...questa funzione viene eseguita solo quando ci sono due dita sullo schermo...
},
three: function (hand, finger1, finger2, finger3) {
// ...
}
// ...
});
In questo modo, potremmo inserire nella funzione di callback associata alla proprietà one
la rilevazione dello spostamento di un dito singolo (parametro finger
) per muovere un oggetto nella pagina, mentre nella funzione two
potremmo gestire due dita (parametri finger1
e finger2
) e usare la variazione della distanza tra i due punti per applicare funzionalità di "pinch" e "zoom" all'oggetto, passando poi a three
, four
, five
per gesture ancora più complesse, fino ad any
che equivale al primo esempio analizzato, lasciando alla libreria l'onere di chiamare la funzione corretta in base al numero di dita usate.
Simulare il mouse
Oltre al rilevamento del tocco, è possibile abilitare la ricezione degli eventi del mouse che simulano il tocco passando il valore booleano true
come secondo parametro in fase di inizializzazione:
Touchy(touchMe, true, function(...) { ... });
Touchy(touchMe, true, { one: ..., two: ... });
Questa opzione può tornare utile sia nelle fasi di testing del sito sul desktop o per rendere fruibile il sito anche a coloro che non hanno a disposizione un device con supporto al tocco.
Estensioni e integrazioni
Touchy.js fornisce supporto alla creazione di estensioni della libreria, oltre all'integrazione con altri framework JavaScript.
Creare plugin
Touchy.js consente la creazione di plugin, ossia moduli in cui racchiudere logica riutilizzabile di risposta al tocco che possa essere condivise e applicata a uno o più elementi della pagina, senza duplicare il codice.
Qui di seguito è riportato lo scheletro tipico di un plugin:
Touchy.plugin('myPlugin', function (elem, settings) {
return { one: ..., two: ... };
});
Il metodo plugin() dell'oggetto globale Touchy
consente di associare un nome identificativo al plugin e specificare la funzione che conterrà il codice di gestione degli eventi che si intende "riciclare". La funzione riceverà in input due parametri: elem
, che contiene un riferimento all'elemento del DOM che subirà le azioni dell'utente, mentre settings
contiene valori personalizzati che vengono passati al plugin al momento dell'inizializzazione, per renderlo completamente configurabile tramite la parametrizzazione. La funzione restituirà un oggetto del tutto simile a quello già visto negli esempi analizzati.
Una volta creato il plugin, per attivarlo sul <div>
dell'esempio iniziale, è sufficiente scrivere
Touchy(touchMe, {
myPlugin: { setting1: 'stringa', setting2: true, setting3: 100 }
});
Alla funzione globale viene passato l'elemento del DOM interessato e un oggetto che possiede una proprietà avente lo stesso nome del plugin da utilizzare, valorizzata con i parametri di configurazione da passare al plugin stesso.
Supporto a JQuery
Touchy.js include un "wrapper" per consentirne l'uso con JQuery. Il codice da scrivere è semplicissimo:
$('#touch-me').touchy({ one: ..., two: ... });