「スマート」ツールチップ
訪問者がマウスをその上に移動させた場合にのみ、要素の上にツールチップを表示する関数を作成してください。通過した場合は表示しません。
言い換えれば、訪問者が要素の上にマウスを移動させてそこに留まると、ツールチップを表示します。もしマウスが通過しただけなら、余計な点滅は不要なので表示する必要はありません。
技術的には、要素上でのマウスの速度を測定し、速度が遅ければ「要素の上に来た」とみなし、ツールチップを表示します。速度が速ければ無視します。
それのための汎用オブジェクト new HoverIntent(options)
を作成します。
その options
elem
– トラックする要素。over
– マウスが要素に到達した場合に呼び出す関数。つまり、ゆっくり移動するか、要素の上に停止した場合です。out
– マウスが要素から離れたときに呼び出す関数(over
が呼び出された場合)。
ツールチップにそのようなオブジェクトを使用する例
// a sample tooltip
let
tooltip =
document.
createElement
(
'div'
)
;
tooltip.
className =
"tooltip"
;
tooltip.
innerHTML =
"Tooltip"
;
// the object will track mouse and call 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
(
)
;
}
}
)
;
デモ
マウスを「時計」の上に速く移動させても何も起こりません。ゆっくりと移動させるか、その上で停止させると、ツールチップが表示されます。
注意: カーソルが時計のサブ要素間を移動しても、ツールチップは「点滅」しません。
アルゴリズムは単純に見えます
- 要素に
onmouseover/out
ハンドラーを配置します。ここでもonmouseenter/leave
を使用できますが、これらは汎用性が低く、デリゲーションを導入すると機能しません。 - マウスカーソルが要素に入ったら、
mousemove
で速度の測定を開始します。 - 速度が遅い場合は、
over
を実行します。 - 要素から出ていて、
over
が実行された場合は、out
を実行します。
しかし、速度をどのように測定するのでしょうか?
最初のアイデアは、100ms
ごとに関数を実行し、前の座標と新しい座標間の距離を測定することです。それが小さい場合、速度は小さいということになります。
残念ながら、JavaScriptで「現在のマウス座標」を取得する方法はありません。 getCurrentMouseCoordinates()
のような関数はありません。
座標を取得する唯一の方法は、mousemove
のようなマウスイベントをリッスンし、イベントオブジェクトから座標を取得することです。
したがって、mousemove
にハンドラーを設定して座標を追跡し、それらを記憶しましょう。そして、100ms
ごとに比較します。
追記:解決策のテストでは、ツールチップが正しく機能するかどうかを確認するために dispatchEvent
を使用しています。