TreeView Control: Using TreeView with Custom Icons

次の例の「Using TreeView with Custom Icons」は、ノードカスタムアイコンを表示する例だが、これを行うのに、「CSS Sprites」という方法が用いられている。
Exampleのページでは、「CSS Sprites」の詳細説明として、www.alistapart.comの文献(CSS Sprites: Image Slicing’s Kiss of Death; written by Dave Shea)へのリンクが貼られている。この文献はImageをSliceすることについて、詳細に書かれていて面白いのだが、このサンプルで用いられているCSSの書式のは、「Hovers」セクションで説明されている。
このCSS Spritesを使うと、細かい多数のimageではなく、それをまとめた大きなimageを伝送することになる。これは一見不利に思われるが、この方法の正当性を説明するものとして、YUI BLogの「Performance Research, Part 1: What the 80/20 Rule Tells Us about Reducing HTTP Requests」という文献が紹介されている。
内容は要するに「imageをたくさん表示する場合、HttpServerがパラレルに処理できるコネクション数がボトルネックになってしまう。なので、imageをまとめてレスポンスしてしまうことで、パラレルなデータ伝送が可能となり、UIのパフォーマンスがよくなる」ということらしい。
なので、「CSS Sprites」で一度にイメージをクライアント(ブラウザ)に送ってしまい、クライアントで切り出した方がいい、ということだ。

当然、これは、イメージに限ったことではない(HttpServerの処理についての話なので)。
だが、これはブロードバンド環境下(もしくはLAN環境下)の話だろうな、と思う。
Ajax自体が、オブジェクトを断片化してHttpServerと通信する処理形態であるのだから(非同期で処理を進めることで体感速度を上げるにしても)、ワールドワイドに考える場合には、イメージのサイズを適切なサイズに保たねばならないのは、当然のことだ。(Google Mapがそうであるように)
世の中、いろいろな考え方があって面白い。

前置きが長くなったが、このExampleは、このCSS Spritesをつかって、イメージを抜き出すやり方のサンプルである。

サンプリング結果の画面は以下で、これは(トップの説明の日本語化以外)YUIのExampleを変わらない。

以下に、このソースの全文を示す。Scriptの配置位置をかえるに際し、module patternで書き直しをおこなった。

<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/treeview/assets/skins/sam/treeview.css" />

<!-- ダウンロードファイルのbuild下にはないので、examples/treeview/assets
             から cssフォルダーとimgフォルダーをとってくる。-->
<link rel="stylesheet" type="text/css" href="scripts/yui/treeview/assets/css/folders/tree.css" />

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

#treewrapper {
	background: #fff; 
	position:relative;
}
#treediv {
	position:relative; 
	width:250px; 
	background: #fff; 
	padding:1em;}
	
/*以下がCSS Spritesをおこなっている部分*/
.icon-ppt { 
	display:block; 
	height: 22px; 
	padding-left: 20px;
	background: transparent url(scripts/yui/treeview/assets/img/icons.png) 0 0px no-repeat; 
}
.icon-dmg { 
	display:block; 
	height: 22px; 
	padding-left: 20px; 
	background: transparent url(scripts/yui/treeview/assets/img/icons.png) 0 -36px no-repeat; 
}
.icon-prv { 
	display:block; 
	height: 22px; 
	padding-left: 20px; 
	background: transparent url(scripts/yui/treeview/assets/img/icons.png) 0 -72px no-repeat; 
}
.icon-gen { 
	display:block; 
	height: 22px; 
	padding-left: 20px; 
	background: transparent url(scripts/yui/treeview/assets/img/icons.png) 0 -108px no-repeat; 
}
.icon-doc { 
	display:block; 
	height: 22px; 
	padding-left: 20px; 
	background: transparent url(scripts/yui/treeview/assets/img/icons.png) 0 -144px no-repeat; 
}
.icon-jar { 
	display:block; 
	height: 22px; 
	padding-left: 20px; 
	background: transparent url(scripts/yui/treeview/assets/img/icons.png) 0 -180px no-repeat; 
}
.icon-zip { 
	display:block; 
	height: 22px; 
	padding-left: 20px; 
	background: transparent url(scripts/yui/treeview/assets/img/icons.png) 0 -216px no-repeat; 
}

.htmlnodelabel { 
	margin-left: 20px; 
}
</style>

<!-- 読み込むjs --> 
<script type="text/javascript" src="scripts/yui/yahoo-dom-event/yahoo-dom-event.js" >
</script> 
<script type="text/javascript" src="scripts/yui/treeview/treeview-min.js" >
</script>

<script type="text/javascript">
//モジュールパターンで実装する。
YAHOO.namespace("EGP");

YAHOO.EGP.IconTree = function() {
	var tree;

    var buildIconTree = function() {
	
	//treeのインスタンス化
	var tree = new YAHOO.widget.TreeView("treediv");
	var root = tree.getRoot();
	
	// TextNodeで実装
	var ahmedDocs = new YAHOO.widget.TextNode("Ahmed's Documents", root, true);
	// 以下は子要素の処理
	// nodeのlabelStyleを種別を設定することで、アイコンを変化・表示する。
	var ahmedMsWord = new YAHOO.widget.TextNode("Prospectus", ahmedDocs, false);
	ahmedMsWord.labelStyle = "icon-doc";
	var ahmedPpt = new YAHOO.widget.TextNode("Presentation", ahmedDocs, false);
	ahmedPpt.labelStyle = "icon-ppt";
	var ahmedPdf = new YAHOO.widget.TextNode("Prospectus-PDF version"
                                             , ahmedDocs, false);
	ahmedPdf.labelStyle = "icon-prv";

	//HTMLNodesで実装
	var sushDocs = new YAHOO.widget.TextNode("Susheela's Documents", root, true);
	// 以下は子要素の処理
	// HTML nodeのcontentStyleに設定することで、アイコンを変化・表示する。
	var sushZip = 
             new YAHOO.widget.HTMLNode("<span class=\"htmlnodelabel\">Zipped Files</span>",
                                    sushDocs, false, true);
	sushZip.contentStyle = "icon-zip";
	var sushDmg = 
            new YAHOO.widget.HTMLNode("<span class=\"htmlnodelabel\">Files -- .dmg version</span>", 
                                  sushDocs, false, true);
	sushDmg.contentStyle = "icon-dmg";
	var sushGen = 
            new YAHOO.widget.HTMLNode("<span class=\"htmlnodelabel\">Script -- text version</span>", sushDocs, false, true);
	sushGen.contentStyle = "icon-gen";
	var sushJar = new YAHOO.widget.HTMLNode("<span class=\"htmlnodelabel\">JAR file</span>", sushDocs, false, true);
	sushJar.contentStyle = "icon-jar";

	tree.draw();
		
    };

    return{
    	init: function() {
        	buildIconTree();
    	}
    };
    
}();

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

<!-- class=" yui-skin-sam"の指定が必要 -->
<BODY class=" yui-skin-sam">
<div id="container">
<div id="treewrapper">
<p>
カスタムアイコンを表示する例です。<br/>
アイコンは1つのimageから、
<a href="http://www.alistapart.com/articles/sprites">CSS Sprites</a>
という方法で切り出されています。<br/>
CSS Spritesの有効性は
<a href="http://yuiblog.com/blog/2006/11/28/performance-research-part-1/">YUI Blog</a>
の記事を参照のこと。
</p>
	<div id="treediv"></div>
</div>
</div>
</BODY>
</HTML>