連載:AjaxでるインタラクティブWebアプリケーション (1)

Ajaxフォトアルバムのフェードイン画像フレームを作ろう


田中 孝太郎
dotimpac.to
2005/11/11

目次
ページ内の項目をクリックするとスクロールします。
ページ内リンクでスムーススクロール@ZEROBASE CASTを使用しています
Ajaxで作るインタラクティブWebアプリケーション JavaScriptライブラリによるAjaxフレームワーク Hello Ajax! フェードイン表示される画像フレームをつくる

 
 Hello Ajax! フェードイン表示される画像フレームを作る

 さてここから、実際にAjaxアプリケーションの制作に入っていきたい。まず今回は、フォトアルバムで画像を表示する際のフレームとなる部品を作る。サンプルを見てみよう。

 リンクをクリックすると、まず写真風のフレームがフェードインで表示され、画像自体はロードが完了してからフェードインする。このサンプルではXMLHTTPRequestを使っていないが、イベントやローディングをJavaScriptで制御しながら、ユーザーにはそれを感じさせないなめらかなインターフェイスを与えるこのようなアプローチは、まさにAjaxの発想だ。


画面3 サンプル(WindowsIE6、Firefox1.0、Safari1.3.1で動作確認済)

 ライブラリをダウンロードする

 今回のサンプルを試してみるために、まずはPrototypeとscript.aculo.usのソースをダウンロードする必要がある。現在Prototypeは1.3.1、script.aculo.usは1.0が正式リリースされているが、本連載では開発バージョンであるPrototype 1.4.0、script.aculo.us 1.5を使用したい。script.aculo.us 1.5で、より実用的な機能がサポートされているためだ。これらをダウンロードしてみよう(2005年11月7日現在、script.aculo.us 1.5はRC版がリリースされている)。

・Prototypeをダウンロード
scriptaculous-js-1.5_rc4.tar.gzに同梱されるものを使用してもよい)

  1. Prototypeサイトhttp://prototype.conio.net/に移動
  2. darcs repositoryから pkg/prototype-1.4.0_pre11.tar.gzをダウンロードして保存
  3. アーカイブを展開し、distディレクトリの「prototype.js」を使用する
・script.aculo.usをダウンロード
  1. script.aculo.usサイトhttp://script.aculo.us/に移動
  2. downloadsページからscriptaculous-js-1.5_rc4.tar.gzをダウンロード
  3. アーカイブを展開し、srcディレクトリのjsファイルを使用する

 script.aculo.usのソースは機能別に分割されており、「scriptaculous.js」をスクリプトタグで指定することですべてのソースが読み込まれるようになっている。使う機能のソースのみを個別に指定してもかまわない。

 Prototypeのクラススタイル文法

 ではソースを解説していこう。なおポイントを絞るためJavaScriptの基本的な書式やDHTMLについての解説は省略している。

 このサンプルのソースは、以下のようなファイル構成となっている。

photoframe.html
  ベースのWebページ、スクリプトのインクルード、フレームのテンプレートを記述
・jsディレクトリ
  prototype.js
  scriptaculous.jsおよびscript.aculo.usソース
  photoframe.js
    フォトフレームのスクリプト
・imagesディレクトリ
  spinner.gif
    処理中状態を示すスピナーのanimeted-gifファイル

photoframe.jsを見てもらうと、JavaScriptにしては見慣れないコーディングがされていると思われるかもしれない。全体を見るとこのような構造になっている。

PhotoFrame = Class.create();
PhotoFrame.prototype = {
  initialize: function(...) {
    ...
  },
  showImage: function(...) {
    ...
  },
  setSize: function(...) {
    ...
  }
}

 これは、Prototypeのフレームワークに従った「クラススタイル」の記述である。JavaScriptはプロトタイプベースの言語と呼ばれ、C++やJavaのような厳密なクラスの概念がないが、PrototypeではJavaScriptでクラス風のコーディングができるような機能を用意している。上記部分はJavaScript独特の文法ではあるものの、PhotoFrameというクラスに、コンストラクタである“initialize”と、“showImage”“setSize”というメソッドをそれぞれ定義していることが分かるだろう。このクラスをphotoframe.htmlのリンクタグのonclickにあるように、

new Photoframe(...);

と呼び出すことができる。疑似的にクラスベースOO言語的なコーディングができるわけだ。JavaScriptでの開発に慣れない読者でも、クラスベースの文法を参考にすれば、さほど違和感なくプログラミングできるのではないだろうか。

 DOM操作とフェードインエフェクト

 photoframe.jsの15〜19行目を見ていく。

var template = $('PhotoFrameTemplate').innerHTML
template = template.replace(/%%fname%%/g, fname);
new Insertion.After($('framePointer'), template);
this.setSize(width, height);
new Effect.Appear($(this.id), { from: 0, duration: 0.5 });

 この部分では、写真のフレームと影、画像タグからなるHTMLをページに追加して表示を行っている。フレームのHTMLはphotoframe.htmlにテンプレートとして非表示で埋め込んであるものをコピーしている。createElementでDOM要素を生成していくような方法もあるが、記述が冗長で分かりにくくなり、後から変更する場合も煩雑になるため、構造が動的に変化しない要素はこのような方法でテンプレートをページに埋め込んでおく手法が有効だ。

 ところどころで見られる「$('...')」というコードは、Prototypeが提供する関数("$"という名前の関数が定義されている)で、ここではdocument.getElementById('...')を意味する。つまり上記のコードは、id「PhotoFrameTmplate」要素の中身からコピーしたHTMLを、識別子を置換して名前を設定する処理を行い、Prototypeの関数「Insertion.After」でid 「framePointer」要素の後ろに追加していることになる。

 「new Effect.Appear(...)」はscript.aculo.usによる要素のフェードインエフェクトの指定だ。ここではid「this.id」の要素(直前に追加した写真フレーム部分)を、不透明度0の状態から0.5秒でフェードインする、という指定になっている。このようにscript.aculo.usのエフェクトの多くは、対象要素のidと、エフェクトに指定するオプションをキーワードと数値や関数を関連付けたオブジェクトで渡す仕様になっている。ここでは使用していないが、オプション「afterFinish」にコールバック関数を渡すことで、フェードイン完了後に後処理を行うようなことも可能だ。詳しくはscript.aculo.usのリファレンスを参照してほしい。

・Effect.Appearリファレンス
  http://wiki.script.aculo.us/scriptaculous/show/Effect.Appear

 イベントの登録

 photoframe.jsの39行目では、画像ロード時のイベントリスナを登録している。

Event.observe(this.loadimg, 'load', this.showImage.bind(this), false);

 JavaScriptのイベントモデルはWebブラウザごとに実装が異なり、JavaScriptで記述する際に厄介な部分の1つだが、Prototypeで定義されたEventオブジェクトを使用することで、クロスブラウザ性を保持しながらイベント登録が行える。ここではimageオブジェクト(this.loadimg)の「onload(画像ロード完了イベント)」にthis.showImageというメソッドを実行するよう設定しているわけだが、メソッド名を「this.showImage.bind(this)」という形で与えているのに注意したい。これもPrototypeの機能だ。

 JavaScriptでは、メソッド内の「this」のスコープはメソッドを呼び出したオブジェクトに設定される仕様になっている。したがって、イベントコールバックにクラスメソッドを渡した場合、メソッドの中の「this」はイベントが発生したオブジェクトに(今回のサンプルならばPhotoFrameオブジェクトではなく、onloadイベントの発生したImageオブジェクトに)設定されてしまうのだ。Prototypeでは、これを避けるために「bind」というメソッドを用意している。イベント登録時に「this.showImage.bind(this)」のように「クラス定義時に使用しているthis(ここではPhotoFrameオブジェクト)」を指定しておくことで、コールバック時のthisが想定どおりの値になる。この機能を使うことで、クラスに定義したメソッドをクラス内からイベントに割り付けるような記述が容易になっている。

 このように、Prototypeのフレームワークを使えばオブジェクトの動作に関する記述をクラス定義にまとめることができる。従来JavaScriptのコーディングというと、値はグローバル変数に保持しイベントはタグ内に書き、さらにそれらとは別の場所に関数を書くといった煩雑なスタイルになりがちだったが、クラススタイルの文法で記述することで、部品として再利用が容易になることが分かるだろう。

 ユーザーの操作に対するリアクション

 前述したように、Ajaxアプリケーションではユーザーの行った操作に対して、JavaScriptエンジンが即座にリアクションを返すことが重要である。それがなければ、Ajaxのメリットと呼ばれている点は、むしろユーザーのストレスの原因になってしまう。具体的にはロード中を示すスピナーやプログレスバー、更新されたオブジェクトを示すハイライトなどでユーザーに状態を告知したり、注意を促すようなアクションを盛り込む必要がある。

 フォトフレームサンプルでのインタラクションの手法を解説しておく。まずフレームのテンプレートにはあらかじめgifアニメーションで動くスピナーが表示されるようになっていて、ロード中であることを示している。画像がロードされたら画像を表示する際にこのスピナーは非表示にしている。スピナーを非表示に設定するElement.hideもPrototypeの機能だ。

 またPhotoFrameが呼び出された際、その画像ファイルがすでに表示されている場合はそのフレームがフラッシュするようにハイライトエフェクトを使っている(いわゆるYellow Fade Technique)。9〜13行目の部分だ。

if($(this.id)) {
$(this.id).style.backgroundColor = "#ffffff";
new Effect.Highlight(this.id);
return;
}

「new Effect.Highlight(...)」はscript.aculo.usのエフェクトである。オプションを指定すればフラッシュする色や持続時間を変更できる。

・Effect.Highlightリファレンス
  http://wiki.script.aculo.us/scriptaculous/show/Effect.Highlight

 以上、今回はフォトフレームのサンプルからPrototypeやscript.aculo.usの基本的な使い方を解説した。次回はこの部品を使って複数の写真をフォトアルバム風に表示する部分を解説していきたい。

3/3 次回もお楽しみに

 INDEX

Ajaxフォトアルバムのフェードイン画像フレームを作ろう
  Page1<Ajaxを実感しよう>
最も手軽なインタラクティブアプリ開発環境としてのAjax
  Page2<JavaScriptライブラリによるAjaxフレームワーク>
Piccy: Ajax Photo Album
Page3<Hello Ajax! フェードイン表示される画像フレームを作る>
ライブラリをダウンロードする/Prototypeのクラススタイル文法/DOM操作とフェードインエフェクト/イベントの管理/ユーザーの操作に対するリアクション

古くて新しいAjaxの真実を見極める
「Webインターフェイスの新しい手法」「画期的なWebアプリケーションの仕組み」であるとして開発者たちの人気を集めるAjaxとは何なのか、その真実を見極めてみよう
最終更新 2005/8/2


HTML5 + UX フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

HTML5+UX 記事ランキング

本日 月間