Tool Tip [jQuery] [js]

2017/01に公開(2017/04に加筆修正)

ツールチップは「ふきだし」(漫画などでセリフ等を入れるアレ)と表現されることもありますが、あるオブジェクト(テキストや画像)にマウスオーバーすると表示される補足的な表示のことです(コンテンツによってはわざと重要な情報をツールチップ化する場合もあります)。

古いブラウザなど(あるいは特定の拡張機能を設定したブラウザ)では、とくにjsやcssなどを仕込まなくても、画像の上にマウスオーバーするとalt属性の内容が表示されたりしますが、これもツールチップと呼びます。
画像に限らず、title属性を設定したオブジェクトにマウスオーバーすると、title属性の内容を表示するブラウザもあります(title属性の場合はわりと表示するブラウザが多いようです)。

alt属性やtitle属性を使ったツールチップの場合はテキストのみになりますが、jsやcssなどを使うと画像を扱えるようになったり、表示位置やタイミングなど細かい設定ができます。

いずれにしてもツールチップの情報量が多すぎると、ツールチップの下に隠れてしまう情報が多すぎたり、画面に収まりきらなかったり、ユーザーを困らせてしまうことにもなりかねませんので、使用の際は注意が必要です。
また、ツールチップを表示するトリガーとなるオブジェクトが小さすぎるとマウスをちょっと動かしただけでツールチップがすぐに消えてしまったり、スマートフォンのようなタッチ操作によるデバイスなど、ツールチップに不向きなデバイスもあるので、気を使うことがいろいろあります。
事前に良く考えて、導入しましょう。

ここではjQueryを使った例をご紹介します。


sample

春はあけぼの。やうやう白くなりゆく山際、少しあかりて、紫だちたる雲の細くたなびきたる。

夏は夜。月の頃はさらなり。闇もなほ、蛍のおほく飛びちがひたる。また、ただ一つ二つなど、ほのかにうち光りて行くもをかし。雨など降るもをかし。

出典:清少納言「枕草子」

  • あけぼの
  • 読み:やまぎわ

  • 意味

    趣がある。風情がある。

    Weblio 学研全訳古語辞典


html

<div class="area_tooltips">
    <p>テキスト□テキスト■<em>ツールチップを表示したい画像やテキストなど</em>テキスト□テキスト■テキスト□テキスト■テキスト□テキスト■</p>
    
    <ul class="tooltips">
	    <li>ツールチップの内容・・・画像やテキストなど、emタグの数の分だけliを用意</li>
    </ul>
</div>

※黒い部分をダブルクリックするとソースを選択できるので、コピーして使ってください。

  1. class[area_tooltips](class名任意)に文章や画像をいれる。
  2. ツールチップを表示させたい文言や画像をemタグ(使用タグは任意)で囲む。
  3. class[tooltips](class名任意)内にツールチップの内容として記述。emタグの数だけliタグが必要。emタグの順番とliの順番を一致させる。
  • トリガーとなる(ツールチップを表示させたい文言や画像を特定するための)タグはemタグに限定されません。構造的に問題がない適切なタグを使用してください。この目的以外にも同じタグをclass[area_tooltips](class名任意)内で使用せざるを得ない場合は、classを使うなどセレクタとして特定できるように工夫してください。
  • ツールチップの内容を記述するのにリストを使いましたが、リストにこだわる必要はありません。使いやすいタグを使ってください。

css

.area_tooltips{position:relative;}
.area_tooltips em{
    cursor: pointer;
}
.tooltips{
    display: none;
    position: absolute;
}
.tooltips li{
    display: none;
}

※黒い部分をダブルクリックするとソースを選択できるので、コピーして使ってください。

  1. 1行目:ツールチップを設定する文章(とツールチップのリスト)の親要素にはposition:relative;を指定
  2. 2~4行目:マウス操作が可能なことがわかりやすいように、ツールチップを表示させるオブジェクト(ここではemタグ)にcursorプロパティでポインターを指定。
    さらに背景色をつけたり、hoverで下線が表示されたりするようにするとわかりやすい。
  3. 5~11行目:ツールチップの内容を記述しておくリストの設定。ツールチップが表示されるときの位置を指定するために、親要素にはposition: absoluteを設定しておく。
    また、親要素と子要素両方にdisplay: noneを設定しておく。
  • 装飾的な設定は省略しています。
    必要に応じて、ツールチップの装飾をしてください。ツールチップは重なって表示するので、見やすいようにするために少なくとも背景の設定は必要かと思われます。
    表示サイズも制限しておいたほうが良いと思われます。

js(改修版)・・・2017/04追記

$(function(){
    var pt = [];
    var pl = [];
    var num;
    
    $('.area_tooltips em').each(function(){
        pt.push($(this).position().top);
        pl.push($(this).position().left);
    });
    
    $('.area_tooltips em').mouseenter(function(){num = $('.area_tooltips em').index(this)});
    $('.area_tooltips em').hover(function() {
        $('.tooltips').css({top: pt[num], left: pl[num]}).stop(true,true).animate({opacity: 'show', top: pt[num] + 20},'slow');
        $('.tooltips li').eq(num).show();
    },function(){
        $('.tooltips').stop().animate({opacity: 'hide', top: pt[num]},'fast',function(){
            $('.tooltips li').hide();
        });
    });
});

※黒い部分をダブルクリックするとソースを選択できるので、コピーして使ってください。

  1. 2~3行目:emタグの親要素を基準とした位置を格納するための配列pt(上からの位置)、pl(左からの位置)を用意(配列変数名は任意)。
  2. 4行目:何番目のemタグにマウスオーバーしたかを格納するためのグローバル変数numを用意(配列変数名は任意)。
  3. 6~9行目:emタグの位置を順番に配列に格納
  4. 11行目:マウスオーバーしたemタグが何番目かを変数numに格納(マウスオーバーするたびに格納)
  5. 12~19行目:hoverイベントが発生するたびに、指定した動作をさせる(最初のfunctionでマウスオーバーしたときの動き、次のfunctionでマウスアウトしたときの動き)
  6. 13行目:マウスオーバーしたときに、ツールチップを表示させる前の位置をcss()で指定し、その後animateで対象のemタグより少し下の位置に表示させる。
    not(':animated')stop()はanimate実行中にマウスを動かすことで何度も同じ動作を繰り返さないためのおまじない。
  7. 14行目:マウスオーバーしているemタグに対応するツールチップの内容を表示
  8. 16~18行目:マウスアウトしたときのアニメーションを設定。ツールチップの位置を戻しながら、非表示にする。非表示になってから、ツールチップの内容を隠す。
  • ほかにマウスポインターに追従するような設定にしたり、クリックで表示非表示を切り替えたり、一度表示させたらユーザーが操作しない限り表示しっぱなしにしたり、いろいろなタイプのツールチップが世の中にはあるようです。目的に応じて、ユーザーがわかりやすく使いやすい動作をするように工夫してみてください。
  • ツールチップについてはプラグインや参考コードが結構世の中に落ちているようなので、google先生に聞いてみてください。
  • マウスオーバー/アウトのタイミングで、ツールチップの動作がもたつく不具合があったので、not(':animated')と記述していた部分をstop()に変更しました。
  • 予断ですが、jqueryでhide()/show()すると、cssでいうところのdisplay:none/blockの状態になります。

以下、2017/04追記

実は、上記のjsにはマウスオーバー/アウトのタイミングで、ツールチップの動作がもたつく不具合がありました(現在は改修済みのjsが適用されています)。

結論から言ってしまうと、参考リンクをはっていたにもかかわらずnot(':animated')とstop()とその引数について、よくわかっていなかった&深く考えていなかったってことなんですけど・・・

hoverによってアニメーションが動くオブジェクトが複数ある場合、それらのオブジェクトをマウスですばやく行き来したりすると、なんだか妙な動きになったりします。
先のアニメーションが終わってないのに、別のアニメーションが始まってしまうことによる問題かなーと推測されるので、これを解決するには、別のアニメーションが始まるときに動作中のアニメーションをリセットすればよいんじゃないかなーと予想してみます。

で。アニメーションのリセットってどうするのかなーとなりますが、リセットっていうか、ツールチップのようにhoverでアニメーションを切り替えるような動きの場合、別のアニメーションが始まったら先行のアニメーションはストップさせると良いのかなと。
とすれば、マウスオーバー(正確にはmouseenter)したときにアニメーションがnot(':animated')が動作中か判定するよりもstop()で動きを止めてしまうほうがよいわけです。
んで、stop()にもちょいと一工夫が必要です。

stop()だけだと一時停止というか、先行したアニメーションのトリガーとなるオブジェクトにまたマウスオーバーすると、とまってた時点からアニメーションを再開してしまうので、これまた妙な動きの原因になります。

ちなみに、jqueryのanimateってアニメーションをqueueという入れ物に格納して、指定した動きを順番に実行しているのですが、アニメーションをストップさせるときに、このqueueを破棄したり、終了状態にしたりできるのがstop()の引数です。第一引数と第二引数があり、trueとfalseの組み合わせでいろいろ指定できるので、実験してみてください。
true,trueにすれば、アニメーションのリセット状態(queueを破棄してアニメーションの最終状態)にできるです。

アニメーションのリセットとか考えてたら、bindすればいいのかなーとか、on()を使えば何とかなるんじゃないの?とか考えたので、興味がある人は調べてください。
似たようなことに悩んだら、stop()以外にもqueue()とかdequeue()とかfinish()とかについても調べると良いかもです。コールバック関数の使いどころとか。

bindとかonとか、下のほうに参考リンクも用意しておきますが、詳しくはgoogle先生に訊いちゃった方が理解が深まります。たぶん。きっと!
なお、onはjquery1.7以降、finishは1.9以降で使えます。


スマートデバイスでのツールチップ

ツールチップは通常、オブジェクト(テキストや画像など)にマウスーバーして表示させるものです。
スマートフォンなど画面に触れて操作するスマートデバイスではマウスオーバー(ロールオーバー)という概念がない(というかタップ操作になる)ので、ツールチップを用いると、ユーザーを戸惑わせる可能性があります。

マウス操作では、ツールチップを仕込んである部分に偶然マウスポインターが通りかかれば表示されるため、とくに「ここにマウスポインターを重ねてください」という指示を明記しなくても、ユーザーが気づく可能性があります(多少のデザイン的な補完は必要でしょうが)。
しかし、スマートデバイスの場合はタップでツールチップが表示されることになるため、タップできることがわからないとそのオブジェクトをタップしてくれません。

とくに、リンクにツールチップを仕込んでいると、1回目のタップでツールチップを表示し、2回目のタップでリンク先へジャンプする・・・というもどかしい操作を強いることになります。

スマートデバイスでツールチップを用いる場合は、画面を表示したときにはじめから表示させておく(ユーザーの操作で非表示にできる)とか、タップしてほしいことを明記したり、タップしたくなるデザインにする必要があります。

そもそも、ツールチップを使う必要があるのか、ほかの表現方法のほうがふさわしいのではないか、ということも含めてよく考えて使用しましょう。


戻る

Top