控えめな JavaScript と Ajax を作成するためのガイド

優れたプログラミング手法を取り入れて Web アプリケーションを作成する

Unobtrusive JavaScript (控えめな JavaScript) とは、Web アプリケーションで JavaScript、CSS、HTML 要素を分離する手法です。この 3 つの要素を分離してアプリケーションを編成することで、アプリケーションの管理が容易になり、プラットフォームや Web ブラウザーの種類が違っても、アプリケーションが一貫して同じように振る舞うようになります。この記事を読んで、Web アプリケーション開発にメリットをもたらす、Unobtrusive な手法を取り入れる方法を学んでください。

Joe Lennon, Lead Developer, Core International

Joe Lennon photoJoe Lennon は、アイルランド・コーク出身の 25 歳のモバイル・アプリケーション開発者兼 Web アプリケーション開発者です。勤務先の Core International では、Core のモバイル HR セルフサービス・ソリューションの開発リーダーを務めています。彼は技術に関する執筆活動にも熱心で、これまで DB2 pureXML、Flex、JavaScript、Adobe AIR、.NET、PHP、Python などを話題にした数多くの IBM developerWorks 記事を書いています。2009年の後半には彼の最初の著書、『Beginning CouchDB』が Apress から出版されました。余暇は、趣味の旅行、読書、ビデオ・ゲームを楽しんでいます。


developerWorks 貢献著者レベル

2010年 11月 02日

はじめに

JavaScript アプリケーションや Ajax (Asynchronous JavaScript + XML) アプリケーションを作成するときには、これらのアプリケーションが提供するインタラクティブな機能にばかり気がとられて、Web アプリケーション開発の基本を忘れがちです。JavaScript アプリケーションと Ajax アプリケーションを Unobtrusive (控えめ) な手法で作成することが重要となる理由は、さまざまにあります。まず 1 つに、Unobtrusive な手法ではアプリケーションのロジックをコンテンツから切り離すことができるため、アプリケーションが進化しても、それを容易に保守できるということがあります。さらに、アプリケーションの最も基本的な振る舞いは、プラットフォームや Web ブラウザーの種類が変わっても確実に一貫性が保たれます。したがって、クロスブラウザーの問題は、JavaScript と Ajax の機能を追加するとき以外には考える必要がありません。そしておそらく最も重要な理由として、Unobtrusive な手法で Web アプリケーションを開発するということは、プログレッシブ・エンハンスメント (Progressive Enhancement) の考え方に従うことになります。つまり、この手法で作成したアプリケーションは、JavaScript や特定の JavaScript の機能 (Ajax を含む) に対応しないブラウザーを使用しているユーザーでも実行できるということです。今まで JavaScript アプリケーションを Obtrusive な手法で作成してきた方は、この記事を読んで、JavaScript を使用できるユーザーにはあらゆる機能を利用できるようにする一方で、(JavaScript を使用できないユーザーも含めた) すべてのユーザーが実行できる Web アプリケーションを作成するためのベスト・プラクティスを学んでください。

Unobtrusive JavaScript という言葉は比較的曖昧に定義されていますが、一般的には、一連の優れたプログラミング手法を使用して Web ページおよび Web アプリケーションを作成するプロセスとして受け入れられています。これらの優れたプログラミング手法には以下のものがあります。

  • アプリケーションの JavaScript、CSS、HTML 要素をそれぞれ分離する
  • JavaScript を使用してアプリケーションのプログレッシブ・エンハンスメントを行う (コア機能には JavaScript を使用しない)
  • 繰り返しを減らし、適切な構造を保ち、読みやすく保守もしやすいコードの構造を維持する
  • Web およびアクセシビリティー標準に準拠する

以上のルールに従ってアプリケーションを開発することは、優れた手法となるだけではなく、限られた機能しか使えないユーザーを含め、さまざまな種類の Web ブラウザーや機器を使用する広範なユーザーが実行可能なアプリケーションを開発できることになります。また、この手法で構築されたアプリケーションは、編成および構造に優れ、実行速度が速くなり、バグも発生しにくくなります。

この記事では、アプリケーションをプレゼンテーション、スタイル、振る舞いの各層に分けて作成する方法を説明します。その目的は、インライン CSS や JavaScript イベント処理を使用しないことです。また、Obtrusive JavaScript コードの例をいくつか紹介し、これらのコードが不適切なプログラミング手法であると考えられる原因を探ります。その上で、同じコードを Unobtrusive な手法で作成して修正する方法を Unobtrusive な開発スタイルのベスト・プラクティスに関するガイドラインと併せて説明します。Unobtrusive なコードで特に危険な領域となるのは、Ajax アプリケーションです。アプリケーションにリッチな Ajax インターフェースがあるからといって、Unobtrusive なコードをプログレッシブ・エンハンスメントによる方法で追加できないことにはなりません。この記事では Ajax 機能がもたらす円滑さを利用できないユーザーに代替の機能を提供できるように Ajax 関数を作成する方法を説明します。そして最後に、JavaScript が無効になっていても動的な Ajax ロードを実行可能なアプリケーションの例を詳しく解説します。


振る舞いとコンテンツの分離

Ajax と Web 2.0 が登場する前は、JavaScript は主にクライアント・サイドのフォーム検証、ロールオーバー・イメージ、コンテンツの表示/非表示などといった基本的な機能に使用されていました。これらの機能を可能にするための JavaScript コードはわずかな量であったため、JavaScript の一般的な使用方法は、HTML 文書の <head> セクションにある <script> ブロックの中にいくつかの関数を作成し、例えば、<input type="button" value="Click Me!" onclick="buttonPressed();"> といったように、HTML 要素に onclick などの属性を設定して関数をイベントに関連付けるというものでした。

コードの各部分を分離することに関しては、JavaScript だけに話は終わりません。CSS スタイルにしても、インラインとして組み込まれていることがよくあります。一例として、<input type="button" value="Click Me!" onclick="buttonPressed();" style="background-color: #999" /> というコードがあるとします。

通常、このようなコーディング・スタイルが採られるのは、要素の外観または振る舞いを変更しようとする無邪気な作業に端を発します。けれども、インラインに作成されたコードが増えるにつれ、コードを扱いにくくなるだけでなく、Unobtrusive な手法での開発が困難になります。大規模なアプリケーションともなると、インラインに作成された JavaScript と CSS のコードを変更するのは悪夢のような作業です。変更箇所があまりにも多く、作業の過程でいとも簡単に間違いを犯してしまいがちです。

JavaScript と CSS コードはインラインにコーディングするのではなく、すべて HTML マークアップとは分離してください。HTML マークアップ内には代わりに idclass などの参照属性を使用することで、JavaScript と CSS がこれらの要素を DOM 内で簡単に見つけて識別できるようにします。ボタンの場合には、リスト 1 のように作成し直すことができます。この記事ではすべての例で Prototype JavaScript ライブラリーを使用しますが、お望みであれば、使い慣れているライブラリーや、ライブラリーを使用しないそのままの JavaScript と置き換えても構いません。「参考文献」に、何種類かの JavaSript フレームワークを比較した記事へのリンクを記載してあるので参考にしてください。

リスト 1. JavaScript と CSS のコードを HTML マークアップの中に含めないこと
// HTML code 

<input type="button" value="Click Me!" id="my_button" />

// JavaScript code

$("my_button").observe("click", buttonPressed);

// CSS code

#my_button { background-color: #999; }

CSS および JavaScript コードを HTML マークアップ内に混在させてはならないことと同じく重要なのは、CSS コードを JavaScript の中に含めないことです。例えばリスト 1 に記載されている buttonPressed 関数によって、要素のスタイルが変更される可能性があります。リスト 2 はその一例です。

リスト 2. buttonPressed 関数が不用意に要素のスタイルを変更する例
function buttonPressed() {
    $("my_div").setStyle({
        backgroundColor: "#FF6600",
        fontSize: "12px"
    })
}

見てのとおり、このコードはスタイルを直接操作する良くないコーディングの例であり、これは本来、CSS に任せなければならないジョブです。スタイルを直接操作する代わりに、指定した名前のクラスに CSS を使用してスタイル・プロパティーを定義した上で、そのクラスを JavaScript によって関連オブジェクトに適用しなければなりません。このようにしてリスト 2 のコードを改善した結果が、リスト 3 です。

リスト 3. 改善したコード
// JavaScript code

function buttonPressed() {
    var my_div = $("my_div");
    if(!my_div.hasClassName("highlight")) 
        my_div.addClassName("highlight");
}

// CSS code:

.highlight { background-color: #FF6600; font-size: 12px; }

上記のようにコードを分離すると、コード構造が極めて体系化されるため、問題が発生したとしても簡単に診断して修正できるようになります。さらに推奨される方法は、JavaScript および CSS コードを (<head> セクション内に置くだけだとしても) HTML コードには組み込まずに、外部ファイルに配置することです。外部ファイルに配置すると、大抵はアプリケーションの実行速度が向上することにもなります。外部ファイルは初めてアクセスされるときにキャッシュに入れられるので、次のページで再度ダウンロードする必要がなくなるためです。

技術的には、プログレッシブ・エンハンスメントを採用しながらも、インライン・コードを使用した JavaScript アプリケーションを構築することは可能ですが、その場合、保守しにくい煩雑なコードになってしまいます。可能な限り、JavaScript、CSS、HTML を分離するように努めるのが自分のためです。


Obtrusive JavaScript の例

Obtrusive JavaScript を説明するのに最も手っ取り早い方法は、例を示すことです。例えば、<a href="#" id="my_link">Click me</a> というように作成されたリンクを目にすることは珍しくありません。

この場合、JavaScript コードには $("my_link").observe("click", validateAndSubmit); のようなイベント・ハンドラーが含まれているはずです。

validateAndSubmit 関数には何らかの検証ルールが含まれていて、これらのルールを利用した検証に合格した場合、フォームが送信されるなどのアクションが実行されます。この方法にはまったく問題がないように思えるかもしれませんが、JavaScript が有効でなければ、このリンクは機能しません。ブラウザーは URL # を探します。これは当然、現在表示しているページへのアンカーなので、JavaScript が有効でないブラウザーは停止します。

注: 原則として、クライアント・サイドの検証を当てにしてはなりません。JavaScript は簡単に無効にしたり、回避したりできるため、クライアント・サイドの検証はフォームおよび入力の検証手段としては非常に不確かで、信頼性に欠けます。クライアント・サイドの検証は、ユーザー・エクスペリエンスを改善し、サーバーに送信される無効なフォームの数を減らす手段として使用するべきです。入力は必ず、サーバー・サイドで検証してクレンジングを行ってください。

この場合、クライアント・サイドの検証は、JavaScript が有効にされていなければ何の役にも立ちません。このリンクを修正するには、<a href="page2.html" id="my_link">Click me</a> というリンクを作成するだけの簡単な話です。

これで、リンク先に進むかどうかを JavaScript コードの中で判断することができます (リスト 4 を参照)。

リスト 4. リンク先に進むかどうかの判断
function validateAndSubmit() {
    //validation logic here
    if(valid) {
        return true;
    } else {
        alert("Error!");
        return false;
    }
}

リスト 4 では、valid が false として返されるとアラート・ボックスが開き、イベント・ハンドラーが false の値を返したため、リンク先には飛びません。

Unobtrusive JavaScript は、クイック・ジャンプ用のドロップダウン・リストでもよく使用されます。リスト 5 の例を見てください。

リスト 5. クイック・ジャンプ用ドロップダウン・リスト
// HTML code

<select id="my_select">
    <option value="">Select...</option>
    <option value="http://www.google.com">Google</option>
    <option value="http://www.yahoo.com">Yahoo!</option>
    <option value="http://www.bing.com">Bing</option>
</select>

// JavaScript code

function goToSearch(e) {
    var el = Event.element(e);
    if($F(el).length > 0)
        window.location = $F(el);
}

document.observe("dom:loaded", function() {
    $("my_select").observe("change", goToSearch);
});

上記の例でも同じく、JavaScript が無効にされていると、ドロップダウン・リストから項目を選択しても何も起こりません。問題は、使用可能なページのいずれかにナビゲートするための標準的な HTML の代替手段が欠けていることです。この例を作成し直し、今度はプログレッシブ・エンハンスメントの原則に従って JavaScript 関数を組み込みます (リスト 6 を参照)。

リスト 6. プログレッシブ・エンハンスメント
// HTML code:

<form name="redirect" method="get" action="redirect.php">
<select name="my_select" id="my_select">
    <option value="">Select...</option>
    <option value="http://www.google.com">Google</option>
    <option value="http://www.yahoo.com">Yahoo!</option>
    <option value="http://www.bing.com">Bing</option>
</select>
<input type="submit" value="Go!" />
</form>

上記の例では HTML の <form> 要素を使用して、JavaScript が使用できない場合のリダイレクトを処理するサーバー・サイドのスクリプトを定義しています。JavaScript が無効にされている場合、ユーザーが「Go!」ボタンをクリックすると、クエリー・ストリングに URL を渡した上で、フォームが redirect.php に送信されます。これで、サーバーは有効なオプションが選択されていることを検証し、受け取った入力に応じて出力をリダイレクトすることができます。

この例で JavaScript を使用してプログレッシブ・エンハンスメントを行うには、以下の 2 つの方法があります。

  • ユーザーが検索エンジンを選択していることを検証する
  • 別の HTTP リクエストを Web サーバーに送信することなく、リダイレクトを実行する

早速、JavaScript を使用して上記の改善内容を実装してみましょう (リスト 7 を参照)。

リスト 7. JavaScript を使用した改善内容の実装
// JavaScript code

function goToSearch(e) {
    Event.stop(e);
	
    var my_select = $F("my_select");
    if(my_select.length > 0)
        window.location = my_select;
    else
        alert("You must select a search engine!");
}

document.observe("dom:loaded", function() {
    document.redirect.observe("submit", goToSearch);
});

リスト 7 では、デフォルト・アクションが実行されないようにしてから (フォームがサーバーに送信されないようにします)、検索エンジンが選択されていることを検証します。検索エンジンが選択されている場合、選択された URL にユーザーをリダイレクトします。選択されていなければ、アラート・ボックスにエラー・メッセージを表示します。

お気付きかもしれませんが、リスト 6 の例では「Go!」ボタンを追加しましたが、元の例で処理していたのは <select> 要素自体の onchange イベントです。ここで問題となるのは、送信ボタンも JavaScript も使わずに、この <select> 要素しか含まれていないフォームを送信することはできないことです。「Go!」ボタンを使用しないことにした場合、JavaScript を使用してボタンのスタイルを動的に設定し、JavaScript が有効に設定されているブラウザーではボタンを非表示にするという方法があります。この方法を使えば、JavaScript が有効でないブラウザーではボタンが表示され、JavaScript が有効なブラウザーでは非表示になります。そして、イベント・ハンドラーを <select> 要素の onchange イベントに関連付ければ、HTML と JavaScript 両方の長所を活かすことができます。


Unobtrusive なコードの作成

Unobtrusive なコードを作成するためには、環境によらず共通で使用可能なソリューション、つまり、JavaScript をサポートしないブラウザーでも動作するソリューションを開発するところから始めるのがよいでしょう。最近のほとんどの Web ブラウザーでは、JavaScript を無効にするオプションが組み込まれているか、プラグインが使用できるようになっています。これらの手段を使って、JavaScript を使用するという贅沢を許されていないユーザーの目からサイトを検討してください。

まず始めに、Web ページが提供する必要のある基本的な機能のすべてを実行する HTML コードを、JavaScript を一切使用しないで作成します。入力データを送信する必要がある場合は、実際のアクション属性を設定した <form> タグを使用します。他の項目にリンクしなければならない場合は、昔ながらのハイパーリンクを使用します (ただし、<img><div> などの適切でない要素にイベントを関連付けることはできません)。このようにして、実際に動作するアプリケーションを構築していきます。見栄えを良くする必要も、知っている限りで最も素晴らしいユーザー・エクスペリエンスを提供する必要もありませんが、実際に動作するアプリケーションでなければなりません。

満たさなければならない基本要件を指定する一方で、JavaScript なしでも動作するアプリケーションまたは Web ページが完成したら、次は JavaScript を使ってページのプログレッシブ・エンハンスメントを行う作業に移ります。アプリケーションをこのように開発することで、Web ページで使われている HTML の要素がその要素本来の目的で使われる可能性が高くなるため、よりコードに即した意味を持つページとなります。また、この開発方法に従っていなければ無効になっていたかもしれない機能が、JavaScript を追加した後も使用し続けられるという大きなメリットもあります。

その好例は、特に Ajax アプリケーションに関して言えることですが、<form> タグを使わずにフォーム・フィールドを使用する方法です。今ではアプリケーションにわざわざ <form> 要素を組み込まなくても、送信する必要のある値を document.getElementById のような DOM メソッドで取得し、その値を XMLHttpRequest を使ってサーバーに送信できるようになっています。このように作成したアプリケーションの問題は、デフォルト・イベントが設定されないことです。そのため、最終的にはアプリケーションの有用性が損なわれてしまいます。例えば、検索テキスト・ボックスと、このセクションで説明した XMLHttpRequest を使用してサイトを検索するボタンがあるとします。ただし、このプロセスでは <form> 要素を使用していません。この場合、検索テキスト・ボックスにクエリーを入力して Return キーを押すと、フォームが送信され、検索が実行されると期待するのが当然でしょう。けれども残念ながら、そうはなりません。そして結局は、これと同様の機能を実現するためにキー押下イベントを捕捉する方法を突き止めようと奔走することになるでしょう。皮肉なことに、最初から <form> 要素を使っていたとしたら、Return キーを押せば実際には機能していたはずです。これは、HTML 要素がデフォルトで提供する振る舞いが見過ごされている数多くの例の 1 つで、開発者たちはこのような誤用を毎日のように繰り返しています。

ここで、Unobtrusive なコードを作成する単純な例を取り上げます。例えば、1 つのサムネール画像があり、ユーザーがこのサムネールをクリックすると、ライトボックスにこの画像を拡大したものが表示されるようにするとします (ライトボックスとは、モーダル・ポップアップ・ウィンドウの一種で、これが表示されると、マスク・オーバーレイ効果によってページが背景にフェードインします)。ただ単に <img> タグを作成するだけでなく、このタグには、拡大画像を表示するためのライトボックスを呼び出す onclick イベントを関連付けます。このアプリケーションを、JavaScript のサポートを使用できないユーザーを対象に作成する手順を追っていきましょう。

最初のステップは、達成しようとしている目標の計画を練ることです。希望としては、画像をクリックすると、表示中のページから移動することなく拡大された画像が表示されるようにしたいと思っています。したがって、巧妙なライトボックスの効果を追加したいところですが、ここで必ずやらなければならないことは、必要最小限の基本要件にまで絞り込むことです。HTML だけを使用したソリューションは、非常に単純なソリューションになります (リスト 8 を参照)

リスト 8. HTML のみのソリューション
<a href="large.jpg" id="my_thumb" target="_blank"><img src="thumb.jpg" 
width="50" height="50" alt="My Picture" /></a>

リスト 8 には、ありきたりな HTML だけを使用して基本要件を満たすコードが記載されています。このコードには問題ないものの、見栄えは良くありません。JavaScript での要件では、拡大画像を新しいウィンドウに表示するのではなく、現在のウィンドウにオーバーレイされるライトボックスに表示しなければなりません。それには、リスト 9 のコードを使用することができます (拡大画像の URL を引数として取る openLightbox 関数によってライトボックスが起動されるという前提です)。

リスト 9. shownLargImage() 関数shownLargImage() function
function showLargeImage(e) {
    Event.stop(e);
    var link = Event.element(e).up("a");
    openLightbox(link.href);
}

document.observe("dom:loaded", function(e) {
    $("my_thumb").observe("click", showLargeImage);
});

さらに一歩進めて、サムネールのギャラリーを作成するとしたら、ライトボックスが開くと、そこには各サムネールに対応する拡大画像が表示されるようにしなければなりません。その場合も簡単です。IDを使用する代わりに、クラス名を使用するか、あるいはライトボックスのスクリプトで一般的に使われている rel 属性を使用することで対処できます (リスト 10 を参照)。

リスト 10. サムネール・ギャラリーの作成
// HTML code

<a href="large1.jpg" rel="lightbox" target="_blank"><img src="thumb1.jpg" 
width="50" height="50" alt="Picture 1" /></a>

<a href="large2.jpg" rel="lightbox" target="_blank"><img src="thumb2.jpg" 
width="50" height="50" alt="Picture 2" /></a>

<a href="large3.jpg" rel="lightbox" target="_blank"><img src="thumb3.jpg" 
width="50" height="50" alt="Picture 3" /></a>

// JavaScript code

function showLargeImage(e) {
    Event.stop(e);
    var link = Event.element(e).up("a");
    alert(link.href);
}

document.observe("dom:loaded", function(e) {
    $$("a[rel=lightbox]").each(function(thumb) {        
        thumb.observe("click", showLargeImage);
    });
});

このように最終的な結果は、非常に簡潔で読みやすく、保守が容易なコードになります。イベントを複数の項目に関連付けるにしても、不要な id 属性を使用したり、インライン方式でハンドラーを関連付けたりする必要はありません。このコードを Obtrusive な方法で作成していたとしたら、どうやって対処することになっていたかを考えると身震いします。おそらく、JavaScript に対応しないブラウザーで何も機能しないコードに対して、<a> タグを使うということを考えることすらできません。目に入るのは、<img> 要素にあるインライン onclick ハンドラーと、マークアップ自体に引数として直接渡される拡大画像の URL です。一歩下がって自分が実現しようとしていることが何なのかを入念に検討することで、使いやすく、標準に準拠し、コードに即した意味を持ち、プログレッシブ (漸進的) な方法で巧みなライトボックス機能を提供するソリューションを作成することができました。


Unobtrusive Ajax

Web 2.0 と Ajax アプリケーションの登場は、インタラクティブな Web アプリケーションを作成することに関して、Web 開発者に新たな課題をもたらしました。非同期 HTTP リクエストを使用してデータを取得する場合のメリットは明らかです。Ajax を利用したアプリケーションは応答性に優れ、使いやすいだけでなく、従来のデスクトップ・アプリケーションに迫るほどの有用性があります (優れた設計の Web アプリケーションのほうが従来のアプリケーションよりも有用で使いやすいと主張する人もいます)。

Ajax リクエストを使用する際の問題は、JavaScript アプリケーションを使用できないユーザーを対象とするとなると、あっという間に構想がぼやけてしまいがちになることです。典型的な登録フォームを例に取ると、このタイプのフォームを Ajax 化する方法はさまざまにあります。ユーザー名や E メール・アドレスが他で使用されているものではないことを自動的にチェックしたり、ページを最新の表示に更新することなくフォームを検証したり、さらにはフォームを送信して結果を動的に表示したりすることさえできます。

一例として、ユーザー名とパスワードを入力する単純なフォームがあるとします。フォームが非同期 HTTP リクエストをサーバー・サイドのスクリプトに送信すると、プロセスが正常に完了した場合には「OK」のレスポンスが返され、検証で問題があった場合にはエラー・メッセージが返されます。この HTML フォームのコードは、リスト 11 のような形になります。

リスト 11. 単純なフォーム
<form id="register">
	<label for="username">Username</label>
	<input type="text" name="username" id="username" />
	<label for="password">Password</label>
	<input type="password" name="password" id="password" />
	<input type="submit" value="Register" id="reg_button" />
</form>

最初の問題は明白なはずです。リスト 11 のフォームにはメソッドもアクション属性もありません。つまり、「Register (登録)」ボタンを押しても何も起こらないということです。JavaScript を使えば簡単に id 属性によってフォームを取得し、そのフォームを Ajax で送信できるからと言って、フォームを送信する標準的なメソッドを忘れてよいことにはなりません。代わりに、フォームで 1 つの余分なフィールドを探すサーバー・サイドのスクリプトを作成するという方法があります。このフィールドが使用できない場合には、そのリクエストが通常のフォーム送信によって行われたことになるので、サーバーにページ全体を提供しなければなりません。フィールドの値が 1 に設定されている場合、それは非同期 Ajax 呼び出しを使って行われたリクエストなので、「OK」のメッセージまたはエラーを返すだけでよいのです。したがって当然のことながら、Ajax リクエストでフィールドの値を 1 に設定すれば、ブラウザーが JavaScript をサポートしていない場合、リクエストは実行されません。

変更後のフォームはリスト12 のようになります。

リスト 12. 変更後のフォーム
<form id="register" method="post" action="register.php">
    <label for="username">Username</label>
    <input type="text" name="username" id="username" />
    <label for="password">Password</label>
    <input type="password" name="password" id="password" />
    <input type="submit" value="Register" id="reg_button" />
</form>

上記のフォームを使って、Ajax リクエストを同じサーバー・サイドのスクリプトに送信すると、スクリプトはレスポンスをどのように送信すればよいかを簡単に判別することができます (Ajax フィールドが存在しない場合にはエラーと一緒に登録ページにリダイレクトし、フィールドの値が 1 の場合には単純なメッセージを出力します)。リスト 13 に、このアクションを実行するための (Prototype ライブラリーの助けを少し借りた) JavaScript コードの例を記載します。

リスト 13. フォームを使用して Ajax リクエストをサーバー・サイドのスクリプトに送信するコード
<script type="text/javascript">
    function registerSuccess(transport) {
        if(transport.responseText == "ok")
            alert("Success!");
        else
            alert(transport.responseText);
    }

    function registerFailure(transport) {
        alert(transport.status+' '+transport.statusText);
    }

    function submitUsingAjax(e) {
        Event.stop(e);
        var options = {
            parameters: { 
                ajax: "1"
            },
            onSuccess: registerSuccess,
            onFailure: registerFailure
        }
        $("register").request(options);
    }

    document.observe("dom:loaded", function() {
        $("register").observe("submit", submitUsingAjax);
    });
</script>

リスト 13 では、フォームの submit イベントにイベント・ハンドラーを追加しています。このハンドラーはデフォルトのイベント (フォームの送信イベント) が起こらないようにして、追加の ajax 引数の値を 1 に設定し、元のフォームを使用して URL とデータに対する ajax リクエストを行います。成功の HTTP レスポンス・コードを受け取った場合には registerSuccess 関数が呼び出され、エラーが発生した場合には registerFailure 関数が呼び出されます。


Unobtrusive Ajax のもう 1 つの例

Ajax が特に役立つもう 1 つのシナリオは、多数のデータ・セットをページにグループ化する場合です。これは通常、ページネーションと呼ばれています。例えば一連の検索結果がある場合、一度に数百件以上の検索結果を表示するのではなく、それよりも少ないデータ・セットとして、例えば 10 件のレコードを表示して、ユーザーがページを前後に移動できるようにすることがよくあります。その一例は、Google の検索結果で、ページの最下部には結果のページをナビゲートするためのリンクがあります。

一般に、ページ間を移動する標準的な方法は、データをロードするサーバー・サイドのスクリプトにパラメーターを渡し、出力する結果セットのページを指示することです。ここで問題となるのは、ユーザーが別のページに移動する必要が生じるたびにリクエストをサーバーに再送信しなければならないため、ページが毎回、新しいデータ・セットをリロードするという結果になることです。

Ajax を使えば、データの新しいページを取得している間、ユーザーはページ全体がリロードされるのを見ている必要はありません。ページの該当する部分だけを新しいデータ・セットに置き換えることができるからです。これからその仕組みを 1 つの例で説明します。

何よりもまず必要なのは、いつもの通り、JavaScript を使用できないユーザーを対象にすることです。それには、アプリケーションが従来の方法で動作して、新しいデータ・セットでページが最新の表示に更新されるようにしなければなりません (リスト 14 を参照)。この場合も同じく、サーバー・サイドのスクリプトに ajax フラグを渡して、通常の GET リクエストで呼び出されているのか、Ajax 呼び出しが使われているのかをスクリプトが判断できるようにするという方法を使用します。

リスト 14. JavaScript を使用しないユーザーに対してアプリケーションが動作することを確実にする方法
//HTML code

<div id="results">
    <ol>
        <li>Result 1</li>
        <li>Result 2</li>
        ...
        <li>Result 10</li>
    </ol>

    <a class="paging" href="results.php?page=2">Next Page</a>
    <a class="paging" href="results.php?page=10">Last Page</a>
</div>

サーバー・サイドのスクリプト、results.php は、1 ページ目としてリスト 14 のようなページを生成します。このページでリンクをクリックすると、2 ページ目または最終ページに移動することになります。表示しているのが 1 ページ目でなければ、「Previous Page (前ページ)」と「First Page (先頭ページ)」のリンクが表示されます。最終ページを表示している場合は、「Next Page (次ページ)」と「Last Page (最終ページ)」のリンクは表示されません。さらに、特定のページに簡単にジャンプできるようにページのリストを表示することもできます。では、JavaScript に対応していないブラウザーでも機能するように、このページング・セクションを Ajax 化するにはどうすればよいかと言うと、その方法は実に単純です。まず、ページング・リンクすべてへの参照を取得し、リンクがクリックされてもデフォルトのアクションが実行されないようにします (ブラウザーは現在表示されているページをリンクの href 属性に含まれるページに置き換えます)。次に、href 属性の値を取得し、その値を Ajax リクエストの URL として使用します。そして最後に ajax パラメーターにタグを付けて、サーバー・サイドのスクリプトにこれが Ajax リクエストであることを知らせればよいのです (リスト 15 を参照)。

これによりサーバーは、Ajax による呼び出しか、または通常の GET リクエストであるかに応じて、ページ全体を返すか、あるいは要求されたデータ・セットで置き換えるセクションだけを返します。すると関数が、results div のコンテンツをサーバーから返された HTML に置き換えます。この HTML に含まれているのは、結果の <ol> リストとページネーション・リンク (ページ間を移動すると変更されます) です。

リスト 15. ページング・セクションの Ajax 化
<script type="text/javascript">
    function movePageSuccess(transport) {
        $("results").innerHTML = transport.responseText;
    }

    function movePage(e) {
        Event.stop(e);
        var el = Event.element(e);
        var url = el.href;
        var options = {
            method: "get",
            parameters: {
                ajax: "1"
            },
            onSuccess: movePageSuccess
        }
    }

    document.observe("dom:loaded", function() {
        $$(".paging").each(function(link) {
            link.observe("click", movePage);
        });
    });
</script>

もう 1 つの単純明快な Ajax の例は以上のとおりです。ご覧のとおり、JavaScript を必須の要件にするのではなく、アプリケーションのプログレッシブ・エンハンスメントを行って Ajax を扱うのは比較的簡単です。さらに、Ajax をUnobtrusive な方法で扱った方が、大量の JavaScript を使って強引に同じことを行うよりも遥かに簡単で効率的であるということが、より優れたコーディング手法を採り入れることで実感されるはずです。


まとめ

この記事では、Unobtrusive JavaScript とプログレッシブ・エンハンスメントの概念、そして JavaScript を使わずにアプリケーションを設計してから、JavaScript を利用できるユーザーのために JavaScript を後から追加してユーザー・エクスペリエンスを改善するという考え方を紹介しました。Unobtrusive な手法でアプリケーションを開発する方法について包括的に説明したわけではありませんが、私のように、JavaScript と Ajax を必ずしも Unobtrusive に使用してはいない Web アプリケーションの開発に多大な時間を費やしている方は、この Web 開発の考え方を採り入れることによるメリットの大きさに驚かされたのではないでしょうか。

参考文献

学ぶために

製品や技術を入手するために

  • Prototype は、動的 Web アプリケーションの開発を簡易化するために設計された JavaScript フレームワークです。最新バージョンは 1.6 です。
  • IBM ソフトウェアの試用版を使用して、次の開発プロジェクトを革新してください。ダウンロード、あるいは DVD で入手できます。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development
ArticleID=592265
ArticleTitle=控えめな JavaScript と Ajax を作成するためのガイド
publish-date=11022010