画像カタログを作成する

 画像カタログを作成しますが、まずは簡単なところから始めましょう。任意のフォルダ内にあるJPEG画像の数だけURLを表示し、クリックしたら画像が表示されるようにします。任意のフォルダ内にあるJPEG画像のファイル一覧を取得するには、一覧を取得するためのCGIプログラムを作成する必要があります。UNIXであればls *.jpgとして拡張子がjpgのファイルのみリストアップすることができます。任意のディレクトリの指定ですが、サーバーに問い合わせる際に、ディレクトリ名も一緒に送信します。今まではデータを送信するのには入力フォームを作成し、利用していましたが下記サンプルでは入力フォームにはディレクトリ名を示すエレメントは存在しません。Ajaxでは特に入力フォームがなくてもCGIに渡す形式でサーバーに送れば大丈夫です。これによりゲームなどでフォームを経由せずにリアルタイムに変数内容を送信することができます。
 サーバーからはファイル一覧が返されますが、ls -l *.jpgとしているため、以下のようなファイルパスになります。

./pict01/0001.jpg
./pict01/0002.jpg
./pict01/0003.jpg
./pict01/0004.jpg
./pict01/0005.jpg
./pict01/0006.jpg
./pict01/0007.jpg
./pict01/0008.jpg

 この文字列を<a>タグのhref属性に、そのまま設定すれば文字をクリックした時に画像が表示されます。(サンプルを実行する

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>画像カタログ</title>
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function dataSend(imageDirName,callBackFunctionName)
{
httpObj = createXMLHttpRequest(callBackFunctionName);
if (httpObj)
{
httpObj.open("GET","getFileList.rb?dirName="+imageDirName);
httpObj.send(null);
}
}
// JPEGのみ表示
function displayJPEGData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
resultText = httpObj.responseText;
fList = resultText.split(/\x0a/g);
resultText = "";
for (i=0; i<fList.length; i++)
{
resultText += "<a href='"+fList[i]+"'>"+fList[i]+"</a><br>";
}
$("result").innerHTML = resultText;
}else{
$("result").innerHTML = "お待ちください...";
}
}
// --></script>
</head>
<body>
<h1>画像カタログ</h1>
<form method="get" name="ajaxForm" onSubmit="return false;">
<input type="button" value="pict01の内容を表示" onClick="dataSend('pict01',displayJPEGData)"><br>
<input type="button" value="pict02の内容を表示" onClick="dataSend('pict02',displayJPEGData)"><br>
<input type="button" value="pict03の内容を表示" onClick="dataSend('pict03',displayJPEGData)"><br>
</form>
<div id="result"></div>
</body>
</html>

 このような手法だと、ディレクトリ内の画像ファイル数に応じて動的にリンクが設定されるため、画像の数に応じてスクリプトを変更する必要がないので楽です。しかし、これを画像カタログと呼ぶには難があります。難があるよりサムネールもないので画像カタログとは、いくらなんでも呼べません。そこで、今度はサムネール画像を表示してみましょう。このサムネール画像ですが、画像のあるディレクトリ内にthumbnailフォルダがあり、そこに画像ファイル名と対応したサムネール画像が入っています。つまり以下のようなディレクトリ構成になっています。

pict01
 ┣0001.jpg
 ┣0002.jpg
 ┣0003.jpg
 ┣0004.jpg
 ┗thumbnail
   ┣0001.jpg
   ┣0002.jpg
   ┣0003.jpg
   ┗0004.jpg

 このディレクトリ構成を元に<img>タグのsrc属性にサムネール画像のURLを設定します。これは取得したJPEG画像ファイル一覧のURLを以下のように変更すれば期待するサムネール画像のURLを取得できます。

./pict01/0008.jpg
  ↓
./pict01/thumbnail/0008.jpg

 最後の/の前にthumbnailの文字列を入れる処理は以下のサンプルの赤文字部分が該当します。lastIndexOf()で/の文字を検索し、その前にthumbnailの文字列を連結します。求めたURLをimgタグのsrc属性に設定します。リンクはそのまま画像のパスを指定します。これでサムネール画像が表示され、クリックすると実際の画像が表示されます。(サンプルを実行する

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>画像カタログ</title>
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function dataSend(imageDirName,callBackFunctionName)
{
httpObj = createXMLHttpRequest(callBackFunctionName);
if (httpObj)
{
httpObj.open("GET","getFileList.rb?dirName="+imageDirName);
httpObj.send(null);
}
}
// JPEGのみ表示
function displayJPEGData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
resultText = httpObj.responseText;
fList = resultText.split(/\x0a/g);
resultText = "";
for (i=0; i<fList.length-1; i++)
{
sPtr = fList[i].lastIndexOf("/");
thumbPath = fList[i].substring(0,sPtr) + "/thumbnail" + fList[i].substring(sPtr,fList[i].length);
resultText += "<a href='"+fList[i]+"'><img src='"+thumbPath+"' border='0'></a>";
}
$("result").innerHTML = resultText;
}else{
$("result").innerHTML = "お待ちください...";
}
}
// --></script>
</head>
<body>
<h1>画像カタログ</h1>
<form method="get" name="ajaxForm" onSubmit="return false;">
<input type="button" value="pict01の内容を表示" onClick="dataSend('pict01',displayJPEGData)"><br>
<input type="button" value="pict02の内容を表示" onClick="dataSend('pict02',displayJPEGData)"><br>
<input type="button" value="pict03の内容を表示" onClick="dataSend('pict03',displayJPEGData)"><br>
</form>
<div id="result"></div>
</body>
</html>

 これでサムネール画像は表示されるようになりましたが、画像の数だけ連続して表示されるだけです。通常のカタログは1ページに10枚、20枚といった感じに整列して表示されます。上記のプログラムではimgタグを連続して出力していますが、これを個別のdivタグに出力するようにすれば、キッチリとレイアウトされたところに表示できるようになります。divタグの位置やスタイルなどは外部のスタイルシートファイル (thumb.css) で行います。全て最初からスタイルシートファイルで指定しておく方法と後からJavaScriptで座標値などを設定したり生成することもできます。レイアウトが決まっている場合には、プログラムで生成しても構いませんが、変更される可能性がある場合にはプログラムでは生成せずに、スタイルシートファイルで座標値などは設定しておくべきです。そうしないと、プログラムを作成できる人がいない場合に変更が難しくなってしまうためです。
 サムネール画像を出力するdivタグには全てID名を指定しておきます。プログラムからはgetElementById()によって、指定したIDを持つdivタグにアクセスできるようになります。サンプルではgetElementByid()は関数$で定義しているため$("ID名")として利用できるようになっています。
 また、サムネールをクリックしたら次のページに画像を表示するのではなく、同一ページに表示するようにします。これも表示する画像を出力するためのdivタグを設定しておきます。以下のサンプルでは右上に画像を表示するようにしてあります。
 これで、何となく画像カタログのようなものができました。(サンプルを実行する

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>画像カタログ</title>
<link rel="stylesheet" href="thumb.css" type="text/css" media="all">
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function dataSend(imageDirName,callBackFunctionName)
{
httpObj = createXMLHttpRequest(callBackFunctionName);
if (httpObj)
{
httpObj.open("GET","getFileList.rb?dirName="+imageDirName);
httpObj.send(null);
}
}
// JPEGのみ表示
function displayJPEGData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
resultText = httpObj.responseText;
fList = resultText.split(/\x0a/g);
resultText = "";
for (i=0; i<10; i++)
{
$("thumb"+i).innerHTML = "";
}
for (i=0; i<10; i++)
{
if (i >= fList.length-1) break;
sPtr = fList[i].lastIndexOf("/");
thumbPath = fList[i].substring(0,sPtr) + "/thumbnail" + fList[i].substring(sPtr,fList[i].length);
resultText = "<a href=javascript:viewImage('"+fList[i]+"')><img src='"+thumbPath+"' border='0'></a>";
$("thumb"+i).innerHTML = resultText;
}
}
}
function viewImage(iURL)
{
$("imageView").innerHTML = '<img src="'+iURL+'">';
$("imageView").style.visibility = "visible";
}
// --></script>
</head>
<body>
<h1>画像カタログ</h1>
<form method="get" name="ajaxForm" onSubmit="return false;">
<input type="button" value="pict01の内容を表示" onClick="dataSend('pict01',displayJPEGData)"><br>
<input type="button" value="pict02の内容を表示" onClick="dataSend('pict02',displayJPEGData)"><br>
<input type="button" value="pict03の内容を表示" onClick="dataSend('pict03',displayJPEGData)"><br>
</form>
<div id="thumb0"></div>
<div id="thumb1"></div>
<div id="thumb2"></div>
<div id="thumb3"></div>
<div id="thumb4"></div>
<div id="thumb5"></div>
<div id="thumb6"></div>
<div id="thumb7"></div>
<div id="thumb8"></div>
<div id="thumb9"></div>
<div id="thumb10"></div>
<div id="imageView"></div>
</body>
</html>

 実際の画像カタログとしては他にも処理すべきことは多くあります。画像が10枚以上ある場合には、次のページを表示するためのリンクや、ページ数なども表示していく方が親切です。これは全てJavaScriptで可能なので勉強でやってみるとよいでしょう。
 これら以外の問題点としては、表示された画像の位置が悪いためかなりウィンドウを大きくしないと画像全体が見えません。、画像をドラッグして任意の位置に表示できれば少しはよくなります。そこで、次章からはUI(ユーザーインターフェース)部分について説明していきます。

[第五章 1:違和感の少ないインターフェースへ]
[目次へ]

(2006.1.10)