In questo capitolo andremo un po’ più a fondo sugli eventi del mouse e le loro proprietà.
Nota bene: questi eventi potrebbero derivare non solo da “dispositivi mouse”, ma anche da dispositivi di altro tipo, come telefoni e tablets, nei quali sono emulati per compatibilità.
Tipi di eventi del mouse
Abbiamo visto precedentemente alcuni di questi eventi:
mousedown/mouseup
- Il pulsante del mouse viene premuto/rilasciato su un elemento.
mouseover/mouseout
- Il puntatore del mouse passa sopra/abbandona un elemento.
mousemove
- Ogni movimento del mouse su un elemento genera questo evento.
click
- Scaturito dopo l’evento
mousedown
e quindimouseup
sullo stesso elemento se viene usato il pulsante sinistro del mouse. dblclick
- Generato quando avvengono due click sullo stesso elemento in un piccolo intervallo di tempo. Oggigiorno usato raramente.
contextmenu
- Scaturito quando viene premuto il pulsante destro del mouse. Ci sono altri modi per aprire un menù contestuale, per esempio usando un particolare tasto della tastiera, quindi viene generato anche in quest’ultimo caso e non è propriamente un evento del mouse.
…Ci sono tanti altri eventi, che affronteremo successivamente.
Ordine degli eventi
Come possiamo notare dalla lista appena descritta, un’azione dell’utente può generare eventi multipli.
Per esempio, un click sul pulsante sinistro del mouse genera mousedown
, quando il pulsante viene premuto, quindi mouseup
e click
quando viene rilasciato.
Quando un’azione singola inizia eventi multipli, il loro ordine è fisso. Ossia, i gestori vengono chiamati nell’ordine mousedown
→ mouseup
→ click
.
Premi il seguente pulsante e vedrai gli eventi. prova anche il doppio click.
Nel banco di prova in basso, vengono elencati tutti gli eventi del mouse, e se passa più di un secondo tra uno e l’altro vengono separati da una riga orizzontale.
Possiamo inoltre notare la proprietà button
che permette di rilevare il pulsante del mouse, viene spiegato successivamente.
Pulsante del mouse
Gli eventi relativi al click contengono sempre la proprietà button
, che permette di conoscere esattamente quale pulsante del mouse viene premuto.
Solitamente non lo usiamo per gli eventi click
e contextmenu
, perché il primo avviene solo per il click sul pulsante sinistro, ed il secondo – solo per quelli sul tasto destro.
D’altra parte, i gestori mousedown
e mouseup
potrebbero necessitare di event.button
, in quanto questi eventi vengono generati su qualunque pulsante, quindi button
permette di discriminare tra “mousedown destro” e “mousedown sinistro”.
I valori possibili di event.button
sono:
Button state | event.button |
---|---|
Pulsante sinistro (principale) | 0 |
Pulsante medio (ausiliario) | 1 |
Pulsante destro (secondario) | 2 |
Pulsante X1 (indietro) | 3 |
Pulsante X2 (avanti) | 4 |
La maggioranza dei mouse hanno solo il tasto destro e sinistro, quindi i valori possibili sono 0
o 2
. Anche i dispositivi touch generano event simili al tocco.
Inoltre esiste la proprietà event.buttons
che include tutti i pulsanti attualmente premuti, rappresentati come numero intero, una cifra per pulsante. In pratica questa proprietà viene usata raramente, ma si possono trovare i dettagli su MDN in caso di necessità.
event.which
Codice più antiquato potrebbe fare uso della proprietà event.which
che è un vecchio e non standard modo di ottenere informazioni sul pulsante, con questi possibili valori:
event.which == 1
– pulsante sinistro,event.which == 2
– pulsante centrale,event.which == 3
– pulsante destro.
Attualmente, event.which
è deprecato e non dovremmo usarlo.
Modificatori: shift, alt, ctrl e meta
Tutti gli eventi del mouse includono informazioni circa i tasti modificatori premuti.
Proprietà dell’evento:
shiftKey
: ShiftaltKey
: Alt (oppure Opt per Mac)ctrlKey
: CtrlmetaKey
: Cmd per Mac
Vengono valorizzati a true
quando il tasto corrispondente viene premuto.
Per esempio, il seguente pulsante funziona solamente con Alt+Shift+click:
<button id="button">Alt+Shift+Click qui!</button>
<script>
button.onclick = function(event) {
if (event.altKey && event.shiftKey) {
alert('Urrà!');
}
};
</script>
Cmd
invece di Ctrl
Su Windows e Linux esistono i tasti modificatori Alt, Shift e Ctrl. Su Mac ne esiste uno in più: Cmd, corrispondente alla proprietà metaKey
.
Nella maggior parte delle applicazioni, quando Windows/Linux usano Ctrl, su Mac si usa Cmd.
Ossia: quando un utente Windows preme Ctrl+Enter o Ctrl+A, un utente Mac premerebbe Cmd+Enter o Cmd+A, e così via.
Ne consegue che se vogliamo dare supporto a combinazioni di tasti come Ctrl+click, allora per Mac ha senso usare Cmd+click, che è molto più comodo per utenti Mac.
Anche se volessimo forzare gli utenti Mac a usare Ctrl+click – si va incontro a una certa tipologia di ostacolo. Il problema è che: un click col tasto destro con un Ctrl su Mac viene interpretato come un click sul tasto destro, e genera l’evento contextmenu
, non un click
come su Windows/Linux.
Quindi se vogliamo che gli utenti di tutti i sistemi operativi lavorino si sentano a proprio agio, allora insieme a ctrlKey
dovremmo controllare metaKey
.
Per il codice JS ciò significa che dovremmo controllare if (event.ctrlKey || event.metaKey)
.
Le combinazioni di tasti vanno bene in aggiunta al flusso di lavoro. Quindi se il visitatore usa una tastiera – andranno bene.
Ma in mancanza di questa – allora dovrebbe esserci una maniera per poter “vivere” senza tasti modificatori.
Coordinate: clientX/Y, pageX/Y
Tutti gli eventi del mouse forniscono le coordinate in due modi:
- Relative alla Window:
clientX
eclientY
. - Relative al Document:
pageX
epageY
.
Abbiamo già affrontato la differenza tra le due nel capitolo Coordinate.
In soldoni, le coordinate relative al documento pageX/Y
vengono misurate a partire dall’angolo in alto a sinistra del documento, e non cambiano se la pagina viene scrollata, mentre invece clientX/Y
vengono misurate a partire dall’angolo in alto a sinistra della finestra. Quando la pagina viene scrollata, i loro valori cambiano.
Per esempio, se avessimo una finestra di dimensioni 500x500, ed il puntatore del mouse fosse nell’angolo in alto a destra, allora clientX
e clientY
sarebbero valorizzate a 0
, senza alcuna considerazione del fatto che la pagina sia scrollata o meno.
E se il puntatore fosse al centro, allora clientX
e clientY
sarebbero valorizzati a 250
, senza tenere conto del punto in cui si trovi rispetto al documento. In qualche modo sono simili a position:fixed
da questo punto di vista.
Muovere il mouse sopra il campo di testo per vedere clientX/clientY
(l’esempio è dentro un iframe
, quindi le coordinate sono relative a questo iframe
):
<input onmousemove="this.value=event.clientX+':'+event.clientY" value="Muovi il mouse sopra me">
Prevenire la selezione su mousedown
Il doppio click del mouse ha un effetto collaterale che potrebbe dare fastidio in alcune interfacce: seleziona il testo.
Per esempio, il doppio click sul seguente testo lo seleziona in aggiunta al nostro gestore:
<span ondblclick="alert('dblclick')">Doppio click su di me</span>
Se si preme sul pulsante sinistro del mouse e, senza rilasciarlo, si muove il mouse, si ottiene una selezione, spesso non voluta.
Ci sono vari modi per prevenire la selezione, consultabili nel capitolo Selection e Range.
In questo caso particolare la maniera più ragionevole è di prevenire l’azione del browser su mousedown
. La cosa previene entrambe queste selezioni:
Prima...
<b ondblclick="alert('Click!')" onmousedown="return false">
Double-click me
</b>
...Dopo
Adesso l’elemento in grassetto non viene selezionato al doppio click, e premendo il pulsante sinistro su di esso non comincerà la selezione.
Nota bene: il testo all’interno è ancora selezionabile. Comunque, la selezione dovrebbe cominciare non sul testo stesso, ma prima o dopo di esso. Solitamente la cosa è accettabile per gli utenti.
Se volessimo disabilitare la selezione per proteggere il contenuto della nostra pagina dal copia-incolla, potremmo usare un altro evento: oncopy
.
<div oncopy="alert('Copying forbidden!');return false">
Caro utente,
La copia è vietata.
Sebbene, nel caso in cui tu conosca JS or HTML, allora potrai prendere tutto dal sorgente della pagina.
</div>
Se provassimo a copiare un pezzo del testo all’interno del <div>
, la copia non andrà a buon fine, perché l’azione predefinita oncopy
sarà stata prevenuta.
Sicuramente l’utente ha accesso al sorgente HTML della pagina, e potrà prendere il contenuto da lì, ma non tutti conoscono come farlo.
Riepilogo
Gli eventi del mouse contengono le seguenti proprietà:
-
Pulsante:
button
. -
Tasti modificatori (
true
se premuto):altKey
,ctrlKey
,shiftKey
emetaKey
(Mac).- Se vogliamo gestire Ctrl, allora non dobbiamo dimenticarci degli utenti Mac, che solitamente usano Cmd, quindi sarebbe meglio controllare
if (e.metaKey || e.ctrlKey)
.
- Se vogliamo gestire Ctrl, allora non dobbiamo dimenticarci degli utenti Mac, che solitamente usano Cmd, quindi sarebbe meglio controllare
-
Coordinate relative alla Window:
clientX/clientY
. -
Coordinate relative al Document:
pageX/pageY
.
L’azione predefinita del browser di mousedown
è la selezione del testo, se non è cosa gradita per l’interfaccia, allora dovrebbe essere prevenuta.
Nel prossimo capitolo vedremo più in dettaglio gli eventi che seguono i movimenti del puntatore e come tenere traccia degli elementi che cambiano sotto di esso.
Commenti
<code>
, per molte righe – includile nel tag<pre>
, per più di 10 righe – utilizza una sandbox (plnkr, jsbin, codepen…)