Aspetto
Eventi del mouse
JavaScript.info · Ilya Kantor e contributori. Originale inglese · Edizione italiana · Fonti e licenza.
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 quindi mouseup 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.
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à.
L'obsoleta 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:key:ShiftaltKey:key:Alt(oppurekey:Optper Mac)ctrlKey:key:CtrlmetaKey:key:Cmdper Mac
Vengono valorizzati a true quando il tasto corrispondente viene premuto.
Per esempio, il seguente pulsante funziona solamente con key:Alt+Shift+click:
html
<button id="button">Alt+Shift+Click qui!</button>
<script>
button.onclick = function(event) {
if (event.altKey && event.shiftKey) {
alert('Urrà!');
}
};
</script>Attenzione: su Mac solitamente si usa Cmd invece di Ctrl
Su Windows e Linux esistono i tasti modificatori key:Alt, key:Shift e key:Ctrl. Su Mac ne esiste uno in più: key:Cmd, corrispondente alla proprietà metaKey.
Nella maggior parte delle applicazioni, quando Windows/Linux usano key:Ctrl, su Mac si usa key:Cmd.
Ossia: quando un utente Windows preme key:Ctrl+Enter o key:Ctrl+A, un utente Mac premerebbe key:Cmd+Enter o key:Cmd+A, e così via.
Ne consegue che se vogliamo dare supporto a combinazioni di tasti come key:Ctrl+click, allora per Mac ha senso usare key:Cmd+click, che è molto più comodo per utenti Mac.
Anche se volessimo forzare gli utenti Mac a usare key:Ctrl+click -- si va incontro a una certa tipologia di ostacolo. Il problema è che: un click col tasto destro con un key: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).
Esistono anche i dispositivi mobile
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:
clientXeclientY. - Relative al Document:
pageXepageY.
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.
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:
html
<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:
html
Prima...
<b ondblclick="alert('Click!')" onmousedown="return false">
Double-click me
</b>
...DopoAdesso 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.
Prevenire la copia
Se volessimo disabilitare la selezione per proteggere il contenuto della nostra pagina dal copia-incolla, potremmo usare un altro evento: oncopy.
html
<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 (
truese premuto):altKey,ctrlKey,shiftKeyemetaKey(Mac).- Se vogliamo gestire
key:Ctrl, allora non dobbiamo dimenticarci degli utenti Mac, che solitamente usanokey:Cmd, quindi sarebbe meglio controllareif (e.metaKey || e.ctrlKey).
- Se vogliamo gestire
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.
Esercizi
1 · Lista selezionabile
Create una lista nella quale gli elementi siano selezionabili, come nei file manager.
- Un click su una lista seleziona solo quell'elemento (aggiunge la classe
.selected), e deseleziona tutti gli altri. - Se un click viene fatto insieme a
key:Ctrl(key:Cmdper Mac), allora la seleziona viene alternata sull'elemento, ma gli altri elementi non vengono modificati.
La demo:
Apri l’esempio nella fonte originale.
P.S.: Per questo compito possiamo assumere che questi elementi siano composti solamente da testo. Nessun tag annidato.
P.P.S.: Prevenire la selezione nativa del browser sul testo al click.