js苦手なデザイナーの筆者としては、なるべくならコピペして事なきを得たい…と考えている。
が、仕事をしている以上、コピペしてちょっと手を加えて…という事は避けて通れない。特に、今回は再開発案件だったので、仕様を大きく変更することが難しい。
そこを前提として、下記の要件で絞ってみた。
jsに弱いデザイナーが考えた要件
- ツールチップちっくだけど、マウスオーバーではなくクリックして表示させる
- 再開発前のツールチップは、『閉じる』のボタン以外では閉じない。非常に邪魔。要素外でクリックしても閉じたい
- そもそも『閉じる』ボタンの表示が邪魔だからいらない(とデザイナーは思った)
- 高機能ツールチップもいいけど、少しでも軽量化したかったので、不要なアニメーションとか永遠に使わないオプションはいらない
そこで発見したのが
クリックされたらツールチップを表示するスクリプトをjQueryで組んでみた
…要件ぴったりだと思いました。実装するまでは。
##理想のスクリプト見つけた!しかし…
このスクリプト、HTML側は
<a href="#ツールチップID名" class="clickToolTip">ツールチップ呼びたい</a>
<p id="ツールチップID名" class="toolTip invisible">ツールチップ呼びたいの内容</p>
と書くのですが、<a href="#ツールチップID名"…>
の#
というハッシュが問題。
こちらのページのDEMOを見ると、問題なんてどこにもないのですが、スクロールするような長いページの場合は問題が発生します。
<a href="">
に#
ハッシュが含まれていると、ページの下側でツールチップを開こうとすると、ページが上部に戻ってしまう。
あかん…今回はあかんのや…
そんなこんなで、ない脳みそをぐるぐる回して考えてみた。
その1:ツールチップを表示する<a href="">
に#は使いたくない
そう。
#
は使いたくない。
でも、表示するツールチップ内容のIDと連動してるので、それがないとスクリプトは動かない。でも、あるとページが上部に動く。
というわけで、jsの4行目付近
var targetNote = $(this).attr('href');
これを書き換えればいい。
スクリプトを1カ所書き換えてみる
オリジナルのスクリプトは
$(function(){
$('a.clickToolTip').click(function(){
// リンクの #note** を取得
var targetNote = $(this).attr('href');
// [?]の座標を取得
var position = $(this).position();
var newPositionTop = position.top +10; /* + 数値で下方向へ移動 */
var newPositionLeft = position.left + 35; /* + 数値で右方向へ移動 */
// ツールチップの位置を調整
$('p'+targetNote).css({'top': newPositionTop + 'px', 'left': newPositionLeft + 'px'});
// ツールチップの class="invisible" を削除
$('p'+targetNote).removeClass('invisible');
});
// 表示されたツールチップを隠す処理(マウスクリックで全て隠す)
$('html').mousedown(function(){
$('p.toolTip').addClass('invisible');
});
});
で、つたないデザイナーの私はこう書き換えた。
###タテに長いページでも使えるようにする魔改造その1。
1カ所だけ書き換える。
$(function(){
$('a.clickToolTip').click(function(){
// targetの #note** を取得
var targetNote = $(this).attr('target');
// [?]の座標を取得
var position = $(this).position();
var newPositionTop = position.top +10; /* + 数値で下方向へ移動 */
var newPositionLeft = position.left + 35; /* + 数値で右方向へ移動 */
// ツールチップの位置を調整
$('p'+targetNote).css({'top': newPositionTop + 'px', 'left': newPositionLeft + 'px'});
// ツールチップの class="invisible" を削除
$('p'+targetNote).removeClass('invisible');
});
// 表示されたツールチップを隠す処理(マウスクリックで全て隠す)
$('html').mousedown(function(){
$('p.toolTip').addClass('invisible');
});
});
var targetNote = $(this).attr('href');
を
var targetNote = $(this).attr('target');
と書き換えた。htmlはこう書く。
<table>
<tr>
<th>タイトル <a href="javascript:void(0)" target="#note1" class="clickToolTip">?</a></th>
<td><input type="text" name="title"></td>
</tr>
<tr>
<th>メッセージ <a href="javascript:void(0)" target="#note2" class="clickToolTip">?</a></th>
<td><textarea name="message" rows="5" cols="30"></textarea></td>
</tr>
</table>
<!-- ツールチップで表示させる内容 -->
<p id="note1" class="toolTip invisible">"タイトル"の説明</p>
<p id="note2" class="toolTip invisible">"メッセージ"の説明<br />複数行の内容を<br />書くことも可能。<br /><br />複数行の内容を書くことも可能。<br />複数行の内容を書くことも可能。<br />複数行の内容を書くことも可能。<br />複数行の内容を書くことも可能。</p>
html5だとname
が廃止されてしまったので使えずorz
target
の要素を取り出す暴挙に出ることにした(思い通り動作するなら、悪魔に魂を売るデザイナーです。)。
target
はリンク先の表示方法を指定するので、普通だと別ウィンドウが開くことになる。
任意のウィンドウやフレーム名は使えるわけですが…こんな使い方して良いのだろうか。
でも、今はともかく使えるようにしたいので、魔改造でもなんでもします。
その2:HTMLの構造は死守する。
そもそも、target
の使い方としては微妙なので、あくまでもjs側で頑張ってみる。
$(function(){
// ツールチップ表示処理
$('a.clickToolTip').click(function(){
// リンクの #note** を取得
var targetNote = $(this).attr('href');
// [?]の座標を取得
var position = $(this).position();
var newPositionTop = position.top +10; /* + 数値で下方向へ移動 */
var newPositionLeft = position.left + 35; /* + 数値で右方向へ移動 */
// ツールチップの位置を調整
$('p'+targetNote).css({'top': newPositionTop + 'px', 'left': newPositionLeft + 'px'});
// ツールチップの class="invisible" を削除
$('p'+targetNote).removeClass('invisible');
});
// 表示されたツールチップを隠す処理(マウスクリックで全て隠す)
$('html').mousedown(function(){
$('p.toolTip').addClass('invisible');
});
// aクリックを無効
$('a.clickToolTip').click(function(){
return false;
});
});
a.clickToolTip
のリンクを無効にする暴挙(その2)に出る。
その1とは違い、HTML構造は元のままキレイキレイ。
URLを確認するとわかりますが#note1
とか#note2
とか付いてないことが確認できます。
##その3:結局、もっといい方法がないかと途方に暮れる。
もっと良い方法があるぞコノヤローと思った方は、是非編集リクエストして、ガシガシ書き換えて頂きたい(切実なお願い)。
その4:HTMLの構造は死守する。その2
これを書いた直後にアドバイス貰った−ということで、それの追記。
$(function(){
// ツールチップ表示処理
$('a.clickToolTip').click(function(e){ //イベントオブジェクト(e)を引数に設定
// リンク押下時のデフォルトの動作を無効にする。
e.preventDefault();
// リンクの #note** を取得
var targetNote = $(this).attr('href');
// [?]の座標を取得
var position = $(this).position();
var newPositionTop = position.top +10; /* + 数値で下方向へ移動 */
var newPositionLeft = position.left + 35; /* + 数値で右方向へ移動 */
// ツールチップの位置を調整
$('p'+targetNote).css({'top': newPositionTop + 'px', 'left': newPositionLeft + 'px'});
// ツールチップの class="invisible" を削除
$('p'+targetNote).removeClass('invisible');
});
// 表示されたツールチップを隠す処理(マウスクリックで全て隠す)
$('html').mousedown(function(){
$('p.toolTip').addClass('invisible');
});
});
おー。すっきりした!
前回までは、一番下にリンクを無効にするjs書いてたんだけど、aタグの処理をキャンセルするpreventDefault();
で同じ事をしてるので行数減った。
元のスクリプトは、a.clickToolTip
とか、タイプセレクタから書いていることが多いですけど、最近はタイプセレクタを含んでしまうと、そのタイプセレクタ以外では使えなくなるので良くないって言われてます(筆者も理由がない限り、タイプセレクタは指定しません)。
元スクリプトに敬意を込めて、あえてそのままにしていますが、実際に使用するときは、タイプセレクタなしで書くと良いと思います。.clickToolTip
みたいな感じで。
勿論、ご利用は自己責任でおねがいしますー。
続報 その1 このコードを更に変えたバージョンあり
この記事を最初に書いた後に、更に考えてくれた人がいたらしい。
「『クリックしたらツールチップを表示するスクリプト』をちょっと変えてみた。」をちょっと変えてみた。
こちらはIDで指定せず、相対関係で指定してる。
これ使いやすい−。もうちょっと早く気づいていれば、こちらを実装では使ったかもしれない。毎回ID振るのは面倒ですものねえ。
##続報 その2 作者さんがver.2を作ってくれた。
なんと!作者のtoogieさんが、この拙い記事を発見して、ver.2を作ってくれました。
「クリックしたらツールチップを表示するスクリプト」のバージョン2を作ってみた
IDではなく、データー属性を使ったツールチップです。
詳しくはtoogieさんのサイトでご確認ください。
toogieさん、ありがとうございます!
##スペシャルサンクス
クリックされたらツールチップを表示するスクリプトをjQueryで組んでみた