"Smart" tooltip
Scrivete una funzione che mostri un tooltip su un elemento solo se l’utente sposta il mouse su di esso, e non attraverso di esso.
In altre parole, se il visitatore sposta il mouse su questo elemento e si ferma lì – mostra il tooltip. Se invece ha solo spostato il mouse passandoci sopra, non ce n’è bisogno, d’altronde chi mai vorrebbe altri elementi lampeggianti non desiderati?
Tecnicamente, possiamo misurare la velocità del mouse su un elemento, e se è abbastanza lento possiamo supporre che sta arrivando proprio “sull’elemento”, mostrando il tooltip, se è troppo veloce – lo ignoriamo.
Creare un oggetto universale new HoverIntent(options)
utile allo scopo.
Le opzioni possibili options
:
elem
– elemento da tracciare.over
– una funzione da chiamare se il mouse arriva sull’elemento: ossia, se si muove lentamente o se si ferma sull’elemento.out
– una funzione da chiamare quando il mouse abbandona l’elemento (se è stato chiamatoover
).
Ecco un esempio dell’uso di questo oggetto per il tooltip:
// un tooltip di esempio
let tooltip = document.createElement('div');
tooltip.className = "tooltip";
tooltip.innerHTML = "Tooltip";
// l'oggetto tiene traccia del mouse e chiama over/out
new HoverIntent({
elem,
over() {
tooltip.style.left = elem.getBoundingClientRect().left + 'px';
tooltip.style.top = elem.getBoundingClientRect().bottom + 5 + 'px';
document.body.append(tooltip);
},
out() {
tooltip.remove();
}
});
La demo:
Muovendo il mouse oltre la velocità di “clock” non succede nulla, facendolo lentamente o fermandocisi sopra, viene mostrato il tooltip.
Nota bene: il tooltip non “lampeggia” quando il cursore si muove tra i sottoelementi dell’orologio.
L’algoritmo è semplice:
- Impostare dei gestori
onmouseover/out
sull’elemento. Qui si possono anche usareonmouseenter/leave
, però sono meno universali, e non funzionerebbero se introducessimo l’uso della delegation. - Quando il puntatore è entrato dentro l’elemento, si comincia a misurare la velocità al
mousemove
. - Se la velocità è lenta, eseguire
over
. - Quando si esce fuori dall’elemento, ed è stato eseguito
over
, eseguireout
.
Ma come misurare la velocità?
La prima strategia potrebbe essere: eseguire una funzione ogni 100ms
e misurare la distanza tra le vecchie e nuove coordinate. Se fosse piccola, anche la velocità lo sarebbe.
Sfortunatamente, non c’è modo di ricavare “le coordinate attuali del mouse” in JavaScript. Non esistono funzioni come getCurrentMouseCoordinates()
.
L’unico modo è di mettersi in ascolto sugli eventi del mouse, come mousemove
, e prendere le coordinate dall’oggetto evento.
Quindi impostiamo un gestore su mousemove
per tenere traccia delle coordinate e memorizzarle, per poi confrontarle ogni 100ms
.
P.S.: Nota bene: i test della soluzione fanno uso di dispatchEvent
per vedere se il tooltip funziona bene.