「スマート」ツールチップ
訪問者がマウスをその上に移動させた場合にのみ、要素の上にツールチップを表示する関数を作成してください。通過した場合は表示しません。
言い換えれば、訪問者が要素の上にマウスを移動させてそこに留まると、ツールチップを表示します。もしマウスが通過しただけなら、余計な点滅は不要なので表示する必要はありません。
技術的には、要素上でのマウスの速度を測定し、速度が遅ければ「要素の上に来た」とみなし、ツールチップを表示します。速度が速ければ無視します。
それのための汎用オブジェクト 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 を使用しています。