(jQuery版) マウスオンでカーソルに追従するツールチップを表示。
jQueryを使って、マウスオンでツールチップを表示、表示エリア内ではマウスポインタに追従するツールチップを表示させる方法のメモ。
※ ライブラリーを使わずにネイティブJavaScript(Vanilla JavaScript)だけで実装する方法は前の記事を参照。
HTMLのマークアップとCSSの設定
親要素の領域にマウスポインタが入ったら、子要素にしてあるツールチップを非表示から表示に変更する。
※ JavaScriptのマウスイベントでマウスの動きを捕捉して動的に処理する。
HTMLのマークアップ
マウスオンの判定領域となる親要素「.ag2tip」と、ツールチップ本体になる子要素「.tooltip」を記述。
<div class="ag2tip">
<p>常に表示のコンテンツ内容...</p>
<div class="tooltip"><p>ツールチップの内容...</p></div>
</div>
CSS
子要素「.tooltip」が親要素「.ag2tip」の左上の位置になるように「position」を指定し、非表示(「visibility: hidden;」)に設定。親要素「.ag2tip」内の他の要素よりも上位レイヤーに表示させるために「z-index: +1;」を設定。
マウスが親要素に入ったらJavaScriptで任意のクラス名(ここでは「ag2tipOn」)を動的に付与し、子要素「.tooltip」を表示(「visibility: visible;」)にする。
.ag2tip {
position: relative;
}
.tooltip {
display: inline-block;
position: absolute;
top: 0;
left: 0;
max-width: 100px;
visibility: hidden;
z-index: +1;
}
.ag2tipOn .tooltip {
visibility: visible;
}
jQueryで実装
マウスイベントでマウスポインタの動きを捕捉し、親要素の領域への流入・流出を判別してツールチップの表示、非表示を実行する。
- 「mouseover」イベント : 指定した要素の領域へのマウスの流入で発火。
- 「mouseout」イベント : 指定した要素の領域からのマウスの流出で発火。
- 「mousemove」イベント : 指定した要素の領域上でのマウスの移動で発火。
マウスイベントを使って実装
- 「mouseover」イベントで、マウスポインタの流入を捕捉。
- マウスポインタがクラス名「ag2tip」を持つ要素に流入した場合、その要素に動的にクラス名(ここでは「ag2tipOn」)を付与。
- ポインタの位置座標を取得。
- 子要素「.tooltip」の位置をポインタの座標に変更。(「transform: translate(x,y);」を変更する。)
- マウスポインタが親要素「.ag2tip」上で移動している場合、ポインタ位置座標の取得と子要素「.tooltip」の座標変更を常に実行。(「mousemove」イベントで捕捉。)
- マウスポインタが親要素から流出した場合、動的に付与したクラスを削除。(「mouseout」イベントで捕捉。)
//初期設定値
const ag2tipSettings = {
classWrap: 'ag2tip', //親要素に付与してあるクラス名
classActive: 'ag2tipOn', //マウスオンで親要素に付与するクラス名
classTip: 'tooltip', //ツールチップに付与してあるクラス名
offset: 20 //ツールチップの表示位置をポインタよりも右にずらすピクセル量
};
let currentTip = null;
const ag2tip = {
on: function(e,t){
//クラスを付与
$(t).addClass(ag2tipSettings.classActive);
//現表示の親要素を保持
currentTip = t;
//表示位置を補正
ag2tip.pos(e);
},
off: function(){
//クラスを削除
$(currentTip).removeClass(ag2tipSettings.classActive);
currentTip = null;
},
pos: function(e){
let $thisTip = $(currentTip).find('.'+ag2tipSettings.classTip);
let x,y;
//ツールチップの表示位置をポインタ座標に変更
x = e.clientX - $(currentTip).offset().left + ag2tipSettings.offset;
y = e.clientY - $(currentTip).offset().top + $(window).scrollTop();
$thisTip.css({'transform':'translate('+x+'px,'+y+'px)'});
let thisTipW = $thisTip.outerWidth(),
winW = $(window).innerWidth();
//ツールチップがブラウザウィンドウ右にはみ出る場合にポインタの左側へ移動させる
if(thisTipW + e.clientX + ag2tipSettings.offset > winW) {
$thisTip.css({'left':-(thisTipW + ag2tipSettings.offset + 10)+'px'});
}else{
$thisTip.css({'left':'0px'});
}
}
};
$('.'+ag2tipSettings.classWrap).on('mouseover', function(e){
//ツールチップを保持する要素、かつ現表示の要素でない場合、クラス名を付与
if($(this).hasClass(ag2tipSettings.classWrap) && !$(this).hasClass(ag2tipSettings.classActive)) ag2tip.on(e,this);
});
$('.'+ag2tipSettings.classWrap).on('mousemove', function(e){
//ツールチップが表示中の場合
if(currentTip) ag2tip.pos(e);
});
$('.'+ag2tipSettings.classWrap).on('mouseout', function(e){
//ツールチップが表示中の場合
if(currentTip){
//マウス移動先がウィンドウ外ではない場合
if(e.relatedTarget){
//移動元が現表示の親要素、かつ移動先がその子要素の場合
if( $(e.target).hasClass(ag2tipSettings.classActive) && $.contains(e.target,e.relatedTarget) ) return;
//移動元が現表示の親要素の子要素、かつ移動先が現表示の親要素(またはその子要素)の場合
if( $.contains(currentTip,e.target) && ( $(e.relatedTarget).hasClass(ag2tipSettings.classActive) || $.contains(currentTip,e.relatedTarget)) ) return;
}
//それ以外の場合はクラス名を削除
ag2tip.off();
}
});
https://memo.ag2works.tokyo/post-4043/
(jQuery版) マウスオンでカーソルに追従するツールチップを表示。 | memo メモ [AG2WORKS]
<a href="https://memo.ag2works.tokyo/post-4043/" target="_blank" rel="noopener">(jQuery版) マウスオンでカーソルに追従するツールチップを表示。 | memo メモ [AG2WORKS]</a>
この記事へのコメント (2件)
うごかないじゃん!!!!!!
個人的なメモのサイトでそんなこと言われてもという感じですが、記事内のJavaScriptのコードを2ヶ所修正しました。
1. 初期設定値。
修正前「classTip: 'tip'」→修正後「classTip: 'tooltip'」
(HTMLのマークアップの記述と違っていたので。)
2. 'mouseover'内のコード。
修正前「$(e.target)」→修正後「$(this)」
(「ag2tip」の要素にpaddingが無く、子要素に直接のmouseoverだと「$(e.target)」では正しく捕捉されないので。)