torna alle lezioni

"Smart" tooltip

importanza: 5

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 chiamato over).

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.

Apri una sandbox con i test.

L’algoritmo è semplice:

  1. Impostare dei gestori onmouseover/out sull’elemento. Qui si possono anche usare onmouseenter/leave, però sono meno universali, e non funzionerebbero se introducessimo l’uso della delegation.
  2. Quando il puntatore è entrato dentro l’elemento, si comincia a misurare la velocità al mousemove.
  3. Se la velocità è lenta, eseguire over.
  4. Quando si esce fuori dall’elemento, ed è stato eseguito over, eseguire out.

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.

Apri la soluzione con i test in una sandbox.