2009年3月19日

JavaScript

JavaScript の不思議な面白さ - 第三回

  • このエントリーをはてなブックマークに追加

第二回」では、グレー文字入り入力欄という課題への解答例としました。
プログラムの設計といったものがどんなものなのか、その面白さが少しでも伝わっていれば幸いです。
とはいえ、動いてさえいればあとはどれも似たようなもので、あとはプログラマの自己満足の世界です。その中での創意工夫はプログラマに閉じた世界とはいえ、ポケットの中に広がった空ではないかと思っています。

前回の最後の問題の答えを示す前に一つ重要なことを忘れていました。
そうです、使ってもらう為にはライブラリ化が必要でした。

 *

三回目となるこの記事からは、皆さんお待ちかねの関数化・ライブラリ化といったプログラムを隠す手法を試していこうと思います。ロジックの複雑化や高機能化につれてこうした手法はさまざまな手法が開発され技術の進歩は目覚しいなと感じさせる分野です。

今回は例として示すプログラムの量が多くなっていますが、どれも同じことを形を変えて実現しています。細部にはこだわらずぱっと見の印象でプログラムをつかんでいただければと
さて、今回の内容に関しては達人といっていい先輩諸氏がいらっしゃるのでそうした先達の知恵を拝借していきましょう。
思います。

軽く調べた結果、

・DOM 操作を利用すべき
・onclick onmousedown などは使うべきでない
・JavaScript や CSS を外部ファイル化すべき
・ライブラリ化すべき

といったところです。
ふーん、そんなものかと思って眺めていただければ結構です。

今回は実際にこれらを試してみましょう。

簡単な例:A

<form>   
<input name="q" type='text' style='color:gray'  
    onfocus='if( this.value=="ここで検索!" ){ this.value=""; this.style.color=""};'  
    value="ここで検索!" />   
<input type="submit" value="検索"/>   
</form>

これは最初に提示したごく簡単な例です。
この例はよくない状態であるということになりますので、これを分離していきます。

tech blog 20090319
「プログラムを分離してみたものの...」

簡単な例を分離した例:B

<form>
<input name="q" type="text" id="input" value="ここで検索!" />   
<input type="submit" value="検索"/>
</form>

<script type="text/javascript" ><!--

function addGrayDesc(id){
	var i = document.getElementById(id);
	i.style.color = "gray";
	var desc = i.value;
	addEvent( i, "focus", function(){
		if( this.value == desc ){
			this.value="";
			this.style.color="";
		}
	});
}

function addEvent( obj, type, fn ){
	if (obj.addEventListener){
		obj.addEventListener( type, fn, false );
	}else if (obj.attachEvent){
		obj["e"+type+fn] = fn;
		obj[type+fn] = function() {
			obj["e"+type+fn]( window.event );
		}
		obj.attachEvent( "on"+type, obj[type+fn] );
	}
}
addGrayDesc("input");

//--></script>

ライブラリ化の手順として最初にまず「分離」を行います。HTML と JavaScript の混在していた部分を視覚的にもわかるレベルで細かい部品に分けて一つにまとめます。

出来上がったコードはずいぶんと巨大化してしまいました。簡単な例ではなんとか目で追えば理解できそうだったプログラム部分も、もはやこの時点では動くことを祈るのみになっています。急に複雑になってしまったのは onfocus の利用をやめた為にブラウザ分岐が必要になってしまった為です。

しかしここで終わりではなく、分離の次は隠す作業が待っています。

簡単な例を分離し隠した例:C

<script type="text/javascript" src="mylibrary.js"></script>

<form>
<input name="q" type="text" id="input" value="ここで検索!" />
<input type="submit" value="検索"/>
</form>

<script type="text/javascript" ><!--

addGrayDesc("input");

//--></script>

B に比べ中間の JavaScript 部分がごっそり分離されました。
ここまでで一つの完成系としておきます。

これが正しい姿である、と言われてしまえばそんなものかとも思えますし、プログラムも簡単な例と比べても違和感はありません。もちろんこの程度では納得できない方は、さらに見た目の短さを追及することも可能です。

次は、HTML 部分も含めてプログラム内に格納してみます。

HTML 部分をプログラム内に格納した例:D

<script type="text/javascript" src="mylibrary.js"></script>

<form>
<script type="text/javascript" ><!--

function createInput(desc){
	document.write('<scr'+'ipt type="text/javascript" src="mylibrary.js"></scr'+'ipt>');
	document.write('<input name="q" type="text" id="input" value="'+desc+'" />');
	addGrayDesc("input");
}

createInput("ここで検索!");
//--></script>
<input type="submit" value="検索"/>
</form>

プログラムの中に HTML のようなものが部分的に格納されているのがわかります。
こうすることでさらにこの全体を分離・隠すことが可能になります。

すべてを隠した例:E

<script type="text/javascript" src="mylibrary2.js"></script>
<form>
<script> createInput("ここで検索!"); </script>
<input type="submit" value="検索"/>   
</form>

そしてこれが全力でコードを隠した結果です。かなりシンプルになりました。
同じ事を同じように実現し、同じように動作する5つのコードができました。

こうした作業にどれだけ価値を見いだせるか。
プログラマであればこうした、すでに動作しているコードを別の形で表現しなおすといったことは、誰でも一度は経験したことのある作業ではないでしょうか。

 *

ここまで、ABCDEと作ってきました。
ここから先はかなり好みの入る世界になってきます。

このなかから強いてひとつ採用するならどれがよいでしょうか?
また改善するならどうするべきでしょうか?

(Yahoo!メール開発チーム 田淵純一)

(2009/3/26追記)
>>第四回へ

Yahoo! JAPANでは情報技術を駆使して人々や社会の課題を一緒に解決していける方を募集しています。詳しくは採用情報をご覧ください。

  • このエントリーをはてなブックマークに追加