Indicare le cose sul web era semplice. Avevi un mouse, l'hai spostato in giro, a volte premi i pulsanti, ed è tutto. Tutto ciò che non era del mouse è stato emulato come tale e gli sviluppatori sapevano esattamente su cosa contare.
Tuttavia, semplice non significa necessariamente che sia buono. Nel corso del tempo, è diventata sempre più importante che non tutto fosse (o abbia finto di essere) un topo: potevi fare penne sensibili alla pressione e inclinate, per una straordinaria libertà creativa; potresti usare le dita, quindi tutto ciò di cui servivano il dispositivo e la mano; e hey, perché non usare più di un dito mentre ci sei?
Si sono verificati eventi touch per un po' di tempo per aiutarci, ma sono API completamente separate appositamente per il tocco, che ti costringe a programmare due modelli di eventi separati se vuoi supportare sia il mouse che il tocco. Chrome 55 viene fornito con uno standard più recente che unifica entrambi i modelli: eventi puntatore.
Un modello a evento singolo
Gli eventi del puntatore unificano le modello di input del puntatore per il browser, che unisce tocco, penne e mouse in un unico insieme di eventi. Ad esempio:
document.addEventListener('pointermove',
ev => console.log('The pointer moved.'));
foo.addEventListener('pointerover',
ev => console.log('The pointer is now over foo.'));
Ecco un elenco di tutti gli eventi disponibili, che dovrebbe esserti familiare se hai familiarità con gli eventi del mouse:
pointerover
|
Il puntatore è entrato nel riquadro di delimitazione dell'elemento.
Questo avviene immediatamente per i dispositivi che supportano il passaggio del mouse o prima di un
pointerdown evento per i dispositivi che non lo fanno.
|
pointerenter
|
Simile a pointerover , ma non mostra bolle e punti di manipolazione
discendenti in modo diverso.
Dettagli sulle specifiche.
|
pointerdown
|
Il puntatore è nello stato di pulsante attivo e un pulsante è o un contatto, in base alla semantica del dispositivo di input. |
pointermove
|
Il puntatore ha cambiato posizione. |
pointerup
|
Il puntatore ha lasciato lo stato del pulsante attivo. |
pointercancel
|
È successo qualcosa che significa che è improbabile che il puntatore emetta più eventi. Ciò significa che devi annullare le azioni in corso e per tornare allo stato di input neutro. |
pointerout
|
Il puntatore ha lasciato il riquadro di delimitazione dell'elemento o della schermata. Anche dopo un
pointerup , se il dispositivo non supporta il passaggio del mouse.
|
pointerleave
|
Simile a pointerout , ma non mostra bolle e punti di manipolazione
discendenti in modo diverso.
Dettagli sulle specifiche.
|
gotpointercapture
|
L'elemento ha ricevuto l'acquisizione del puntatore. |
lostpointercapture
|
Il puntatore in fase di acquisizione è stato rilasciate. |
Diversi tipi di input
In genere, gli eventi puntatore consentono di scrivere codice in modo indipendente dall'input,
senza dover registrare gestori di eventi separati per i diversi dispositivi di input.
Ovviamente, dovrai comunque fare attenzione alle differenze tra i tipi di input, ad esempio se
si applica il concetto di passaggio
del mouse. Se vuoi distinguere i diversi tipi di dispositivi di input, magari per fornire
separatamente codice/funzionalità per i diversi input, ma puoi farlo
all'interno degli stessi gestori di eventi utilizzando la proprietà pointerType
dell'elemento
PointerEvent
a riga di comando. Ad esempio, se stavi programmando un riquadro di navigazione a scomparsa laterale, potresti
avere la seguente logica sul tuo evento pointermove
:
switch(ev.pointerType) {
case 'mouse':
// Do nothing.
break;
case 'touch':
// Allow drag gesture.
break;
case 'pen':
// Also allow drag gesture.
break;
default:
// Getting an empty string means the browser doesn't know
// what device type it is. Let's assume mouse and do nothing.
break;
}
Azioni predefinite
Nei browser abilitati al tocco, alcuni gesti vengono utilizzati per far scorrere, aumentare lo zoom o aggiornare la pagina.
Nel caso di eventi touch, riceverai comunque gli eventi mentre questi predefiniti
sono in corso. Ad esempio, touchmove
verrà comunque attivato mentre l'utente scorre la pagina.
Con gli eventi del puntatore, ogni volta che viene attivata un'azione predefinita come scorrimento o zoom,
riceverai un evento pointercancel
per farti sapere che il browser ha eseguito
controllo del puntatore. Ad esempio:
document.addEventListener('pointercancel',
ev => console.log('Go home, the browser is in charge now.'));
Velocità integrata: per impostazione predefinita, questo modello consente prestazioni migliori. rispetto agli eventi touch, per i quali bisognerebbe usare Listener di eventi passivi per raggiungere lo stesso livello di reattività.
Puoi impedire al browser di assumere il controllo con
touch-action
proprietà CSS. Se viene impostato su none
in un elemento, vengono disattivati tutti
azioni definite dal browser avviate su quell'elemento. Ma ci sono una serie di
altri valori per un controllo più granulare, ad esempio pan-x
, per consentire
il browser in modo che reagisca al movimento sull'asse x ma non sull'asse y. Chrome 55
supporta i seguenti valori:
auto
|
Valore predefinito; il browser può eseguire qualsiasi azione predefinita. |
none
|
Il browser non è autorizzato a eseguire azioni predefinite. |
pan-x
|
Il browser può eseguire solo l'azione predefinita di scorrimento orizzontale. |
pan-y
|
Il browser può eseguire solo l'azione predefinita di scorrimento verticale. |
pan-left
|
Il browser può eseguire solo l'azione predefinita di scorrimento orizzontale, e solo per spostare la pagina verso sinistra. |
pan-right
|
Il browser può eseguire solo l'azione predefinita di scorrimento orizzontale, e solo per spostare la pagina verso destra. |
pan-up
|
Il browser può eseguire solo l'azione predefinita di scorrimento verticale. e solo per spostare la pagina verso l'alto. |
pan-down
|
Il browser può eseguire solo l'azione predefinita di scorrimento verticale. e solo per eseguire la panoramica della pagina verso il basso. |
manipulation
|
Il browser può eseguire soltanto azioni di scorrimento e zoom. |
Acquisizione del puntatore
Ti è mai capitato di trascorrere un'ora frustrante a eseguire il debug di un mouseup
guasto
finché non ti renderai conto che è perché l'utente ha lasciato il pulsante.
al di fuori del target di clic? No? Ok, forse sono solo io, allora.
Eppure, non c'era un modo davvero valido per affrontare questo problema. Certo,
puoi impostare il gestore mouseup
sul documento e salvare lo stato
dell'applicazione per tenere traccia delle cose. Non è la soluzione più pulita,
Tuttavia, in particolare se devi creare un componente web e cercare di mantenere tutto in regola
e isolata.
Gli eventi puntatore offrono una soluzione molto migliore: è possibile acquisire il puntatore,
per assicurarti di ottenere quell'evento pointerup
(o qualsiasi altro dei suoi eventi
amici).
const foo = document.querySelector('#foo');
foo.addEventListener('pointerdown', ev => {
console.log('Button down, capturing!');
// Every pointer has an ID, which you can read from the event.
foo.setPointerCapture(ev.pointerId);
});
foo.addEventListener('pointerup',
ev => console.log('Button up. Every time!'));
Supporto browser
Al momento della scrittura, gli eventi puntatore sono supportati in Internet Explorer 11. Microsoft Edge, Chrome e Opera e parzialmente supportato in Firefox. Puoi consulta un elenco aggiornato all'indirizzo caniuse.com.
Puoi utilizzare il polyfill degli eventi puntatore per colmare le lacune. In alternativa, il controllo del supporto del browser in fase di runtime semplice:
if (window.PointerEvent) {
// Yay, we can use pointer events!
} else {
// Back to mouse and touch events, I guess.
}
Gli eventi Puntatore sono ideali per il miglioramento progressivo:
modifica i metodi di inizializzazione per effettuare il controllo riportato sopra, aggiungi evento puntatore
nel blocco if
e sposta i gestori di eventi mouse/touch nel
Blocco else
.
Quindi, provali e facci sapere la tua opinione.