jQueryでツールチップ!マウスオーバーで吹き出しの表示!
今回は、jQueryでマウスオーバーで吹き出しを表示させるツールチップの作成方法について、サンプルコードを交え記載してみたいと思います。
ツールチップというのは、主にリンクなどにマウスをのせたときに、補足的な情報を表示させるものになります。実は、ブラウザにも標準で付いており、要素のtitle属性を入力しておくと、ツールチップが表示されます。しかし、ツールチップのデザインを、オリジナルなものにしたい場合もあると思いますので、jQueryを利用して、オリジナルデザインのツールチップ自作方法を記載してみます。
という事で、それでは今回はッ、
- ・ツールチップをどう作るか
- ・ツールチップの属性値を要素にする
- ・ツールチップの表示!
- ・ツールチップ内の改行を考慮
- ・マウスが外れたらツールチップを非表示
上記について記載していこうと思います…。
ツールチップをどう作るか
それでは、私がいぜん自作したものをサンプルとして記載してみたいと思います。
それでは上記を参考に、ツールチップの作り方を記載してみようと思います。まずは、HTMLソースを記載してみます。
<p>九州から北海道まで<br>
<span class=”sub_title_txt”>桜の見頃</span>をご案内!</p>
<ul>
<li><img src=”images/sakura1.png” class=”tooltip” id=”sakura1″ data-tooltip=”1.宮崎県:母智丘公園の桜”></li>
<li><img src=”images/sakura2.png” class=”tooltip” id=”sakura2″ data-tooltip=”2.福岡県:舞鶴公園の桜”></li>
<li><img src=”images/sakura3.png” class=”tooltip” id=”sakura3″ data-tooltip=”3.広島県:千光寺公園の桜”></li>
・・ 以下省略 ・・
</ul>
</div>
マークアップを見てみますと、li要素にdata-tooltipという属性がついています。これはHTML5のdata属性になります。本来であれば、title属性を使うのが好ましいのですが、ブラウザ実装のツールチップが表示されるのを避けるため、data属性を利用しています。
その他には、id=”sakura1″、これはCSSでポジション指定なのであまり関係ありません、それ以外はtooltipというクラスがついているだけで、特に変わったところはありません。
では、どんなふうにjQueryのコードを記述すればよいのか、考え方を記載してみます。
・deta-tooltip属性をとり出し、div要素にする。
・ツールチップを表示する位置を計算する
・表示、非表示は、アニメーション系メソッドを利用する
考え方としては、上記のようになります。それでは実際に、少しずつコードを記述してみます。
ツールチップの属性値を要素にする
まずは表示するツールチップ自体を作成していきます。今回ツールチップの内容に利用するのは、li要素に付記してあるdata-tooltip属性の属性値です。これはあくまで属性の値なので、divなどの要素を作って、その中にテキストとして挿入していきます。
$(“.tooltip”).each(function(){
var toolTip = $(‘<div class=”tooltip-body”>’);——①
var toolTipText = $(this).attr(“data-tooltip”);——②
toolTip.html( ‘<p$gt;’ + toolTipText + ‘</p><span class=”tail”></span>’ ).hide();——③
$(“body”).append(toolTip);——④
});
});
まずは.tooltipに対して、以前にご紹介いたしました、each()メソッドを利用します。
①では、少し見慣れないコードだと思います。まず、var toolTipと記述して、変数toolTipを宣言しています。見慣れないコードはその後で、
$(‘<div class=”tooltip-body”>’);
上記の意味をご説明します。今までは$(“セレクタ”)として、このような記述方法でした。セレクタを記述するのであれば、下記のような記述になることと思います。
$(‘div.tooltip-body’);
しかもHTMLのマークアップには、tooltip-bodyというクラスの付いたdiv要素は見あたりません。実は、これはセレクタとして記述しているわけではありません。<div class=”tooltip-bpdy”>のように、HTMLをそのまま記述すると、jQueryではその要素(要素ノードという)を生成してくれます。実際にHTML上にマークアップされていない要素でも、jQueryでは簡単に生成することができます。
以前記載したhtml()メソッドなどでも、このように要素を生成して挿入していました。今回は、属性値であるdata-tooltipの値を、div要素で表示したいため、このように新しいdiv要素を作りました。そのdiv要素を、変数toolTipに代入しておきます。
var toolTip = $(‘<div class=”tooltip-body”>’);
それでは②に付いて記載してみます。
このコードは簡単で、data-tooltip属性の値を、toolTipTextという変数に代入しています。
続く③では、先ほど作成した変数toolTip(div要素が入っています)に、html()メソッドを使って、p要素と変数のtoolTipText、span要素を挿入しています。
そして最後にhide()メソッドを記述しています。これについては後述します。この段階では、変数toolTipには下記のようなオブジェクトが代入されていることになります。
<div class=”tooltip-body”>
<p>(data-tooltipの値)</p>
<span class=”tail”></span>
</div>
上記が画面に表示されるときのツールチップになります。また、span要素がついていますが、これは矢印のようなデザインをCSSで付けることを前提に記述しています。またデザインによっては必要ない場合もあるかと思いますので、その場合は記述しなくても問題ございません。
それでは④について、この行ではappend()メソッドを使って、先ほど作成したtoolTipをbody要素の最後に挿入しています。ツールチップ自体は、ウィンドウに対して、position:absolute(絶対配置)で配置していく前提として、この位置にしています。
ここで一旦③のコードhide()メソッドに戻り、コードの中のhide()メソッドを、一度削除してブラウザで確認すると、bodyの末尾に、ツールチップが表示されることと思います。また、開発ツールで確認をすると、jQueryによって挿入されたdiv要素が確認できることと思います。
ツールチップの表示!
次はツールチップを表示していきます。表示するタイミングは、マウスにのったときということにするので、mouseenter()メソッドを利用しますが、マウスが外れたときの処理もしていくことになるので、ここではhover()メソッドを使うことにします。
そしてhover()メソッドのイベントハンドラに、アニメーションで表示する処理を書き加えていきます。しかし少し工夫が必要なのが、表示する位置です。ツールチップ自体は、絶対配置で表示することにしましたから、表示する座標が必要になってきます。とりあえずサンプルコードを記載してみます。
$(“.tooltip”).each(function(){
var toolTip = $(‘<div class=”tooltip-body”>’);
var toolTipText = $(this).attr(“data-tooltip”);
toolTip.html( ‘<p>’ + toolTipText + ‘</p><span class=”tail”></span>’ ).hide();
$(“body”).append(toolTip);
$(this).hover(function(){——①
if( toolTip.css(“display”) === “none” ){——②
var targetPostion = $(this).offset();——③
var toolTipHeight = toolTip.height();——④
toolTip.css({
“position”: “absolute”,
“top”: targetPostion.top – toolTipHeight -3 + “px”,——⑤
“left”: targetPostion.left + “px”,——⑥
“display”:”block”,
“opacity”: “0”,
“z-index”: “9999”
})
.stop().animate({——⑦
“top” : “-=10px”,——⑦
“opacity”: “1”——⑦
}, 250);——⑦
}
});
});
});
それでは上記サンプルの説明を記載してみます。
まず①の部分は、$(this)、つまり.tooltip(li要素)に対して、hover()メソッドを利用します。そしてその中に、ますはマウスがのったときの処理の記述になります。
②のコードは「もし、toolTipが非表示だったら」という条件分岐になります。すでにツールチップが表示されている場合には、処理を行う必要がないので、上記のように大きくくくっています。
③では、offset()メソッドが登場します。
offset()メソッドは、ドキュメント(ページ)上の座標位置を取得できます。取得できる値は、topとleftの二つです。この座標の位置を使って、ツールチップの位置を決めていきます。どの位置を取得しているかというと、$(this)なので、マウスがのっているli要素の位置となります。
また、それをtargetPositionという変数に代入しておきます。
続く④のコードは、toolTipHeightという変数に、toolTip(中身はdiv.tooltip-body)の高さを代入しています。先ほどのoffset()メソッドで取得した座標は、あくまでもマウスがのった要素の位置になります。そこにそのままツールチップを表示すると、li要素と重なってしまいます。なのでツールチップの高さ分だけ、上にずらす必要があります。そのためにツールチップの高さを取得しておきます。
<div class=”tooltip-body”>
<p>テキスト</p>
</div>
.tooltip-body{
height: 50px;
padding: 10px;
border: 2px solid red;
}
上記のようなCSSでは、height()メソッドで取得する値は、CSSにほ記述されているように50pxになります。しかし実際に画面上に表示される領域は、上下paddingや上下borderも含めて、74pxになります。
.tooltip-body{
border: 2px solid red;
}
.tooltip-body p{
height: 50px;
padding: 10px;
}
上記の場合は、.tooltip-body自体にはheightは記述されていませんが、子要素であるp要素の高さとpaddingを含めたものが高さになるので、70pxがheight()メソッドで取得できる値になります。これはjQueryの仕様という訳ではなく、CSSの仕様になります。CSSの記述によって、取得できる値が変わることに注意が必要です。
取得した座標と高さを適用し、不透明度を変更
それでは、取得した座標や高さを利用して、コードの続きを記載してみます。
toolTip.css({
“position”: “absolute”,
“top”: targetPostion.top – toolTipHeight -3 + “px”,——⑤
“left”: targetPostion.left + “px”,——⑥
“display”:”block”,
“opacity”: “0”,
“z-index”: “9999”
})
CSS()メソッドで、ツールチップの位置や、その他のスタイルを記述しています。まずは絶対配置で表示するので、position:absoluteを指定しています。
⑤の部分では、先ほど取得した座標や高さが利用されています。
targetPostion.topにはtopの位置が、toolTipHeightには、高さが代入されているので、下記のような数式になります。
“top”:(topの位置) – (ツールチップの高さ) – 3 + “px”,
topの位置から、ツールチップの高さを引き算して、さらに微調整のための3を引いています。最後に文字列の「px」を加えています。
⑥の部分では、そのままtargetPostion.leftをそのまま指定しています。
また、ここではopacity(不透明度)を0にしておくのがポイントです。位置は決まっても、この段階では表示されていません。
.stop().animate({——⑦
“top” : “-=10px”,——⑦
“opacity”: “1”——⑦
}, 250);——⑦
上記⑦アニメーションの部分は、メソッドチェーンで、stop()メソッド、animate()メソッドをつないでいきます。stop()メソッドは、現在実行中のアニメーションを強制的に終了させるメソッドです。animate()メソッドの前に付けることで、アニメーションの繰り返し、重複を防ぐことができます。上記のような記述方法は、tipsとして覚えておくと便利なことと思います。
animate()メソッドで、少し変わった指定方法があるのでご説明いたします。
“top” : “-=10px”,——⑦
上記のように記述すると、「現在の位置」から上方向に10pxずらすことができます。逆に下にずらす場合は、”+=10px”と記述します。
opacityの部分は「1」とします。先ほどCSS()メソッドでは「0」としていました。最後にスピード「250」を指定してアニメーションは完成になります。これでツールチップが上方向に10px移動しながら、フェードインして表示されるアニメーションになります。
ツールチップ内の改行を考慮
「ツールチップの表示!」の前半で、ツールチップを表示する位置を取得するために、offset()メソッドやheight()メソッドを利用して、座標やツールチップの高さを取得しました。特に高さは、li要素とツールチップが重ならないようにオフセットさせるために必要な値です。
ここでスマートフォンなどのブラウザ幅が狭い場合、右端ギリギリの位置にツールチップが表示された場合が下記になります。
ツールチップの中が改行されて、高さが高くなっています。そのせいでオフセットする高さが足らず、li要素に重なってしまっています。
これでは、表示方法としてあまり良くありません。そこでツールチップの高さを取得するタイミングを調整してみます。
$(“.tooltip”).each(function(){
var toolTip = $(‘<div class=”tooltip-body”>’);
var toolTipText = $(this).attr(“data-tooltip”);
toolTip.html( ‘<p>’ + toolTipText + ‘</p><span class=”tail”></span>’ ).hide();
$(“body”).append(toolTip);
$(this).hover(function(){
if( toolTip.css(“display”) === “none” ){
var targetPostion = $(this).offset();
toolTip.css({
“display”:”block”,
“position”: “absolute”,
“left”: targetPostion.left + “px”,——①
“z-index”: “9999”
});
var toolTipHeight = toolTip.height();——②
toolTip.css({
“top”: targetPostion.top – toolTipHeight -3 + “px”,——③
“opacity”: “0”,
})
.stop().animate({
“top” : “-=10px”,
“opacity”: “1”
}, 250);
}
});
});
});
サンプルscript2のコードでは、toolTipをcss()メソッドのleftプロパティで、x軸の配置を決める前に高さを取得していました。サンプルscript3のコードでは、先に①でx軸の配置をしてから、②でツールチップの高さを取得しています。このようにすれば、もしツールチップが画面右に位置して改行されても、その分の高さを取得することができます。
css()メソッドが2回登場することになってしまいますが、これで正しい位置を取得することが可能になります。
マウスが外れたらツールチップを非表示
それでは、マウスが外れたときの処理を記述していきます。hover()メソッドは、イベントハンドラを続けて書くと、mouseleave()メソッドと同じ動きになります。
$(this).hover(function(){
マウスが乗ったとき(mouseenter)
],
function(){
マウスが外れたとき(mouseleave)
});
下記にマウスが外れたときの処理を記述していきます。
$(“.tooltip”).each(function(){
var toolTip = $(‘<div class=”tooltip-body”>’);
・・ 省略 ・・
},
function(){
if( toolTip.css(“display”) !== “none” ){——①
setTimeout(function(){——②
if(!onMouse){——③
toolTip.stop().animate({——③
“top”: “-=10px”,——③
“opacity”: “0”——③
}, 250, function(){——③
toolTip.hide();——③
}——③
);——③
}
}, 1000);——②
}——①
});
});
});
ツールチップが消えるときは、マウスを外してすぐに消えるのではなく、少し時間がたってから消えるようにしています。そして消えるときのエフェクトも、表示するときと同じように、ふわっとアニメーションしながら、フェードアウトしていきます。
コードの説明を記載します。まず、表示するときとは逆に、①if文でdisplayプロパティがnoneでない場合、という条件分岐を付けています。
そして③の部分が、消えるときのアニメーションの部分になります。そのアニメーションを②setTimeout()メソッドで囲んでいます。
setTimeout(function(){・・・},1000)
setTimeout()は、JavaScriptにもともとあるメソッドになります。setTimeout()内に記述した処理を、指定した時間だけ遅らせることができます。上記では、1000ミリ秒たってから、animate()メソッドが実行されることになります。
続くanimate()の部分は、表示するときと同じです。ただし今度はフェードアウトなので、opacity:0にしています。
最後の③の部分は、animate()メソッドで、opacityを0にしたので、表示自体は消えました。しかしopacityが0になっただけで、displayプロパティ的にはblockのままです。なので最後にhide()メソッドを使って、displayプロパティをnoneにしています。
注意したいのが、hide()メソッドを記述する位置になります。上記のコードでは、animate()メソッドの中に記述しています。これを下記のようメソッドチェーンでつないだ場合、
animate({
“top”: “-=10px”,
“opacity”: “0”
}, 250,)
.heide();
上記のようにメソッドチェーンを利用すると、即座にhide()メソッドの処理が実行され、瞬時にツールチップが消えてしまいます。そこで以前記載したように、アニメーションのスピード指定の後ろに、イベントハンドラを記述することをオススメします。そうすることで、アニメーションが実行されてから、hide()メソッドが実行され、最終的にはdisplay:noneとなります。
これで、初めにご紹介したフェードで表示されるツールチップの完成になります。
といことで今回は、jQueryでマウスオーバーで吹き出しを表示させるツールチップの作成方法について、サンプルコードを交え記載しました。
ツールチップが実装できると、表現方法の幅が広がることと思います。また、デザインのアクセントにもなりますし、CSSでも同じような表現方法はございますが、ページのどこでこのアクセントを使うのかがポイントになってくるように思います。今回ご紹介した以前私が作成したページであれば、ページ半分より下に配置してあるので、jQueryでツールチップを表現したわけです。CSSで表現するよりも、比較的HTMLはシンプルで済むことと思います。
とりあえず、今回はここまで…。
お仕事のご依頼は↓コチラより…、それではまた次回…。