POPSブログ

jQuery mouseover tooltip/2

178

  Category:  jquery2012/12/09 pops 

hover()、mouseover()、どちらもマウスが乗ればツールチップを直ぐ表示しますが、アニメ形式では「お祭り騒ぎ」です。直ぐに反応しない様に、遅延タイマー(setTimeout)を組み込んでみます。

 

mouseover()を使用してツールチップを表示する(setTimeout)


mouseover()を使用、setTimeout関数を組み込んだタイプ 2


setTimeout関数を組み込んでみました。一定時間マウスを乗せなければ反応しませんから「お祭り騒ぎ」にはなりません。やはり必要な機能です。但し、setTimeout関数を組み込むと処理が意外と面倒です。

 

Example / マウス位置と、要素のoffsetでの位置調整、食み出し補正。


/// 以下のサンプルには、setTimeout時間、1000ミリ秒が設定されています。///


Example2: ここをマウスでHOVERしてください。これは説明文です。hover()ではなく、mouseover()を使用して制作したものです。(EM1)。
リンク先 : LINK1
ツールチップで説明文などが表示されます。簡単なTOOLTIPです。装飾はCSS3ですからCSS3の機能しないブラウザ(IE78)では角丸陰影にはなりません。表示させたい場所にクラスを設定、text属性に説明文を記述しています。
クラス設定の要素が近接している場合でもそれぞれ固有の「ツールチップのBOX」を作るため多少マウス操作が乱暴でも表示します。尚、表示されない場合はもう一度HOVERすれば表示します。

text属性がない場合は、undefined を返します。

 

下は、LI要素にtool-tipクラスを設定しました。


● 下は、DIV要素に「tool-tip」クラスを設定しました。( W260 x H100 )


注意、text属性は当方が勝手に作った「属性名」です。


BOX幅はJSで、背景色などはCSSで設定可能です。高さは文字数により修正されます。



HTML JS CSS など


HTML

文章の中に span を入れて設定した例

tool-tipクラスを設定。text属性に説明文などを記載します。原則、書き込めるのはテキストであり、html は書き込めません。


通常の設定、spanに文章
<p>文章.....<span class="tool-tip" text="説明文">説明文を表示するエリア。</span>文章.....</p>

text属性は当方が勝手に作った「属性名」ですが jquery では認識して読み出します。


JS

読み込めばすぐに実行する簡易形式です。必要な場合は、JS名、クラス名、ID名などかえて利用ください、その際には関連するCCSなども変更が必要です。

Example2 tool-tip11.js


//tool-tip11.js
//TEST setTimeout
//mouseover mouseout-ACTION

(function($){

	$(function () {

		//表示位置の修正値
		var box_W=300;//チップ横幅 200-400
		//BOXと要素との位置、上方ならマイナス値をいれる
		var posY_v=-10;//自由
		var space=10;//左右余白 10-20
		var speed=400;//アニメ速度 200-800
		//遅延タイマー 200-2000
		var delay_time=1000;//200 750 1000

		//------------------------------------------
		//其の外の変数
		var box_H=60;//暫定値、JSで変更される
		//オブジェクト容器
		var tipitem=[];
		//window幅の取得
		var window_W=$(window).width();
		var timerID=null;
		var no=0;

		//ループ
		$('.tool-tip').each(function (i) {

			//受け渡しカウント
			no=i;

			//mouseover-ACTION
			$(this).mouseover(function (e) {

				//受け渡しオブジェクト
				var obj=$(this);
				//受け渡しイベント
				var event=e;

				//タイマーセット
				timerID=setTimeout(function(){

					//タイトルの取得
					var title_text=obj.attr('text');

					//tipbox個別ID名
					var box_id="tipboxs"+no;

					//残り有れば削除
					if (tipitem[no]) {tipitem[no].remove();}

					//tip-boxを作る
					$('body').append('<div id="'+ box_id +'" class="tip-box"><div class="tip-text">' + title_text + '</div></div>');

					//オブジェクト代入
					tipitem[no]=$('#'+box_id);

					//高さ取得のためtext-box幅決定
					tipitem[no].find('.tip-text').css({'width':box_W-20});
					//tip-boxの高さを計算する/5+5=10
					box_H=tipitem[no].find('.tip-text').height()+10;

					//tip-boxの高さを決める/横幅は規定値
					tipitem[no].css({'width':box_W,'height':box_H});

					//要素の offset page 取得
					var offset=obj.offset();
					var top_p=offset.top;//Y方向
					var left_p=event.pageX;//X方向

					//anime移動終点位置計算
					var top=top_p+posY_v-box_H;
					var left=left_p-box_W/2;//中央補正標準

					//ダイレクト左補正
					if (event.pageX < box_W/2+space) {left=space;}
					//ダイレクト右補正
					if (event.pageX > window_W-(box_W/2+space)) {left=window_W-box_W-space;}

					//CSS初期位置計算、状況に応じ変更できる
					var top_m=top_p;
					var left_m=left_p;

					//内部divブロック非表示
					tipitem[no].find('div').css({'display':'none'});
					//scale処理display:blockのこと
					tipitem[no].css({'width':0,'height':0,'top':top_m,'left':left_m});
					//アニメ実行
					tipitem[no].animate({'width':box_W,'height':box_H,'top':top,'left':left},speed,function(){
						//内部divブロック表示
						tipitem[no].find('div').css({'display':'block'});
					});

				},delay_time);//timer

			});

			//mouseout-ACTION
			$(this).mouseout(function (e) {

				//タイマークリア
				clearTimeout(timerID);

				//tipboxを削除/タイマーがあるのでチップを作っていない時もある
				if (tipitem[no]) {
					tipitem[no].remove();
				}

			});

		});

	});

})(jQuery);

JS中の、注釈文を削除すれば、動作が少々速くなります。


CSS

tool-tip11.css (tool-tip10.cssと同じ)
サンプルでのCSSの例です。現実には、ツールチップ(tip-box)のCSSがあればよい。


/* tool-tip11.css 日本語 */

/* Example2 */
.tool-tip {
cursor:default;/*pointer*/
}
span.tool-tip {
width:auto;
height:20px;
padding:0;
background-color:#DDDDDD;
}


/* tooltip */
.tip-box {
display:block;
position:absolute;
left:0;top:0;
width:300px;
height:60px;
margin:0;
padding:0;
border:1px #333333 solid;
border-radius:5px;
-moz-border-radius:5px;
-webkit-border-radius:5px;
box-shadow: 0 0 6px #333;
-moz-box-shadow: 0 0 8px #333;
-webkit-box-shadow: 0 0 8px #333;
background-color:#FFFFFF;
}

.tip-box .tip-text {
position:absolute;
left:10px;top:5px;
width:280px;
height:auto;
margin:0;
text-align:left;
font-style:normal;
font-size:11px;
/font-size:75%;/*IE67*/
color:#888888;
overflow:hidden;
}

必要なのは tooltip の部分だけです。

現在、上記CSSでは、「span.tool-tip」クラスに「背景色」が設定されています。文章以外の場所に「tool-tip」クラスを指定するときなどは、適正にCSSを書き換えてください。
「IE6.7」で font-size の指定が効かないので、ハックで 75% 指定にしています。使用ページの状況に合わせて下さい。


簡単な解説


基本的には、前ページのJSを改造してみます。setTimeout関数を組み込んだだけですのでほぼ同じですが、
このJSでは、イベントなどを其の都度取得する仕組みになっています。しかし、setTimeout関数の中で$(this)が機能しない、イベントが取得出来ないなどの問題がありますので、最初に変数宣言して参照受け渡しにしました。
基本的な解説などは、前のページを参照ください。


setTimeout関数を使った時の問題点など

setTimeout関数のfunction内部で、$(this)及び、e.pageXなどのイベントは参照受け渡しにする。其の外問題の出る変数は参照受け渡しにするか、グローバルな変数にしないと機能しない。
ここでは、ツールチップ個別のIDを与えているので、多少戸惑う面もあるので注意が必要である。思い道理に機能しない変数はグローバル化すればよい。

ツールチップ個別のIDを与えているのは、削除する前にアニメで初期位置に戻るなどの操作を出来るようにするためである。このサンプルでは直ぐ削除しているが、、。
※ アニメを使用して表示していますので、単にCSSでの表示非表示と比べ、処理が繁雑になります。


取得出来ないものがある
$(this).mouseover(function (e) {

	timerID=setTimeout(function(){

		この内部では

		$(this)が機能しない
		e.pageXなどのイベントが取得出来ない

	},delay_time);//timer
});

以下のようにすれば機能する
$(this).mouseover(function (e) {

	var obj=$(this);
	var event=e;

	//タイマーのセット
	timerID=setTimeout(function(){

		//タイトルの取得
		var title_text=obj.attr('text');

		//要素の offset page 取得
		var offset=obj.offset();
		var left_p=event.pageX;

		其の外の処理

	},delay_time);//timer

	$(this).mouseout(function (e) {

		//タイマークリア
		clearTimeout(timerID);

		其の外の処理

	});
});

問題のある部分を書き換える


ツールチップの削除

タイマーがあるので、ツールチップを作っていない場合もある。一応は判定してから削除実行が理想である。


一応判定してから削除するのが理想
if (tipitem[no]) {
	//tipboxを削除
	tipitem[no].remove();
}

----------------------------------------------

判定しないで実行してもエラーにはならない
tipitem[no].remove();

フェードアウトさせる

単なる削除なら簡単であるが、事前のアニメが進行中のことを踏まえ、削除前にアニメさせる場合は判定、アニメ解除、などの付随処理が必要です。余りアニメさせないでremove()だけで処理するのが簡単。


//tipboxがあるか判定、アニメ解除、フェードアウト
if (tipitem[no]) {
	tipitem[no].stop(false,true);
	tipitem[no].fadeOut(200,function () {
		//tipboxを削除
		tipitem[no].remove();
	});
}

ツールチップの中心に向かって縮小の例

最初のアニメの情報の受け渡しがない場合の例。直接文字形でanimateに代入するのは難しいので、一旦文字形で作ったものを代入している。余り悩むことが無くなる。
現在のツールチップの位置からの計算なので。マウス操作次第では中心に戻るとは限らない。


if (tipitem[no]) {
	//内部divブロック非表示
	tipitem[no].find('div').css({'display':'none'});
	tipitem[no].stop(false,true);
	//位置計算
	var posx='+=' + box_W/2 + 'px';
	var posy='+=' + box_H/2 + 'px';
	//アニメ
	tipitem[no].animate({'width':0,'height':0,'top':posy,'left':posx},200,function(){
		//削除
		tipitem[no].remove();
	});
}

面倒にすれば、自分が悩むだけ。簡単にしておいた方がイイと思う。


hover()形式に変更したい場合


書式を変更するだけで、関数の中は同じです。


$(function () {

	省略

	var delay_time=1000;
	var timerID=null;
	var no=0;

	//ループ
	$('.tool-tip').each(function (i) {

		no=i;

		$(this).hover(function (e) {

			mouseoverでの処理そのまま

			//タイマーのセット
			timerID=setTimeout(function(){

				mouseoverでの処理そのまま

			},delay_time);//timer

		},

		function (e) {

			//タイマークリア
			clearTimeout(timerID);

			mouseoutでの処理そのまま

		});

	});

});


これで「お祭り騒ぎ」解消です。考えるに当節、ツールチップを拡大している「馬鹿」はいないし、「お祭り騒ぎ」を作っているに過ぎない。アニメするとすぐ飽きる。

前のページは、このページのJSの原型です。

【参考】当方の記事: jQuery mouseover tooltip 1



以上です。

 


[ この記事のURL ]


タグ:jquery , memo , series , tooltip

[ jQuery mouseover tooltip シリーズ記事 ]

jQuery tooltip/72012.12.12
jQuery mouseover tooltip/42012.12.11
jQuery mouseover tooltip/32012.12.10
jQuery mouseover tooltip/22012.12.09
jQuery mouseover tooltip/12012.12.08

 

ブログ記事一覧



[1]