Container Family: One Tooltip, Many Context Elements

このExampleでは、1つのTooltipインスタンスを複数のコンテキストに貼り付けるやり方が示されている。YUIのExampleのページの書かれているように、コンテキストごとにTooltipインスタンスを生成するのは(コードとして)如何なものか、と思うので、普通はこういう使い方になるだろう。(YUIのページでは、このことについて「処理速度」を問題にしている。)

ポイントは、以下の点。

  • Tooltipインスタンスを生成する際、context属性を指定を配列指定できる。
  • Tooltipインスタンスのcfgプロパティー(Moduleから継承:Configのインスタンス)から、コンフィグ属性を操作できる。
  • context属性に指定した、context(コンテンツ・エレメント)を監視するカスタムイベントが存在する。

特に、後ろ2点により、Contextにマウスオーバーした際にダイナミックにtooltip属性を変える、といったことが可能になる。一種のlazy loadである。

サンプリングの初期画面は以下。
デフォルトのスタイルを確認するために、YUI Exampleにあるstyle指定は外した。

サンプルは、グループA,Bと大きく分かれていて、グループAはaタグのtitle属性をTooltipのtextとして用い、グループBはダイナミックにTooltipのtextプロパティーを操作する例である。
Tooltipについては、それぞれのグループについて1回ずつのインスタンス生成を行い、そのコンフィグ属性を指定する際に、contextには「aタグ・エレメント」の配列を与えている・

以下が、グループAにおいて、Tooitipを表示した際の画面である。

以下が、グループBにおいて、Tooitipを表示した際の画面である。
グループBについては、context属性の配列には入れるが、実際には表示しないエレメントがある。
これを実装する際には、Tooltipを表示するトリガーを発火させない、という変わった方法をとっている。

以下にJavascriptを含むHTMLの全文を示す。
ソースはモジュールパターンに書き直した。

<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>Ajax_Sampling</TITLE>
<style type="text/css">
body {
	margin:0;
	padding:0;
}
</style>

<link rel="stylesheet" type="text/css" href="scripts/yui/fonts/fonts-min.css" />
<link rel="stylesheet" type="text/css" href="scripts/yui/container/assets/skins/sam/container.css" />
<script type="text/javascript" src="scripts/yui/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="scripts/yui/container/container-min.js"></script>


<style type="text/css" id="defaultstyle">
#main {
	margin: 2px;
	padding: 3px;
	width: 400px;
	height: auto;
	border:1px dashed #999999;
}
</style>

<script type="text/javascript">
//
// モジュールパターンで実装する。
//

YAHOO.namespace("example.container");

// YAHOO.example.containerにTooltipMany を追加する。
YAHOO.example.container.TooltipMany = function() {
	var Event = YAHOO.util.Event;
	var Dom = YAHOO.util.Dom;
	var groupAIds,groupBIds;
	var ttA,ttB;

	// リンクをコンテナに追加する。
	var createLink = function (i, container, title) {
		var a = document.createElement("a");
		a.href = "http://www.yahoo.com/";
		a.innerHTML = i + ". マウスオーバーするとTooltipが現れます。";

		if (title) {
		    a.title = title;
		}

		// Linkをコンテナに追加
		container.appendChild(a);
		// 2行改行。	
		container.appendChild(document.createElement("br"));
		container.appendChild(document.createElement("br"));
		return a;
	};

	// title属性のあるリンク要素の配列を作成する。
	var createTitledLinks = function () {
		var ids = [];
		var container = YAHOO.util.Dom.get("containerA");
		for (var i = 1; i <= 5; i++) {
			// ここでリンクのtitleをセット
			var a = createLink(i, container, "title属性から生成したリンク A" + i + "のTooltip");
			a.id = "A" + i;
			ids.push(a.id);
		}
		return ids;
	};

	// title属性なしのリンク要素の配列を作成する。
	var createUntitledLinks = function () {
		var ids = [];
		var container = YAHOO.util.Dom.get("containerB");
		for (var i = 1; i <= 5; i++) {
			// ここでリンクはtitleをセットしない。
			var a = createLink(i, container, null);
			a.id = "B" + i;
			ids.push(a.id);
			// この3番目の例では、tooltipの発生を抑止する。
			if ( i == 3 ) {
				a.innerHTML = i + ". Tooltipの発生を抑止しています。";
			} 
		}
		return ids;
	};
	
	
	return{
    	init: function() {

		// title属性のあるリンク要素の配列を作成する。
		groupAIds = createTitledLinks();
		// title属性なしのリンク要素の配列を作成する。
		groupBIds = createUntitledLinks();

		// ttA; リンク要素の配列をcontextとして指定
		ttA = new YAHOO.widget.Tooltip("ttA", 
			{ context:groupAIds
			});

		// ttB; リンク要素の配列をcontextとして指定
		ttB = new YAHOO.widget.Tooltip("ttB", 
			{ context:groupBIds
			});

		// ttB; contextMouseOverEventで発火するイベントハンドラ
		// をunscribeする。B3以外ならtrue(tooltipを表示)。
		// B3は表示しない。
		ttB.contextMouseOverEvent.subscribe(
			function(type, args) {
				var context = args[0];
				if (context && context.id == "B3") {
					return false;
				} else {
					return true;
				}	
			}
		);

		// ttB; 表示前にtooltipのtextをセット。
		ttB.contextTriggerEvent.subscribe(
			function(type, args) {
				var context = args[0];
				this.cfg.setProperty("text", 
				context.id + "のTooltipがcontextTriggerEventにより作成された");
			}
		);

		}
	};
}();

//DOMが完全にloadされたら、サンプルを初期化する。
YAHOO.util.Event.onDOMReady(
		//DomReadyイベントで発火するハンドラ
		YAHOO.example.container.TooltipMany.init,
		//ハンドラに渡すオブジェクト(関数)
		YAHOO.example.container.TooltipMany,
		//ハンドラは、上記のオブジェクトのスコープをもつ。   
		true
);

</script>
</HEAD>

<!-- class=" yui-skin-sam"の指定が必要 -->
<BODY class="yui-skin-sam">
<div id="main">
<p>
一つのTooltipインスタンスを使いまわるためのサンプルです。
</p>
	<div class="ttGroup" id="ttGroupA">
		<div class="grphd">Group A: Single Tooltip, textにtilte属性を使います</div>
		<div class="grpbd" id="containerA"></div>
	</div>
	<div class="ttGroup" id="ttGroupB">
		<div class="grphd">Group B: Single Tootip, textをイベントでセットします</div>
		<div class="grpbd" id="containerB"></div>
	</div>

</div>
</BODY>
</HTML>