Ajax による改良: 第 1 回 Ajax と jQuery で既存のサイトを改良する

モーダル・ダイアログによるユーザー・エクスペリエンスの改善とナビゲーションの単純化

Ajax (Asynchronous JavaScript + XML) で既存のサイトを改良する連載の第 1 回目では、単純なモーダル・ウィンドウを使うことで、ポップアップ・ウィンドウを使わないようにし、さらにナビゲーションが脇道にそれて先に進まなくならないようにする方法を紹介します。

Brian J. Dillard (bdillard@pathf.com), RIA Evangelist, Pathfinder Development

Brian DillardWeb 開発者としての 12 年間、Brian J. Dillard は Orbitz Worldwide、Reflect True Custom Beauty、Archipelago LLC、United Airlines といったさまざまな会社のためにリッチなユーザー・インターフェースをビルドしてきました。現在、シカゴの Pathfinder Development で RIA の熱烈な支持者として活躍する彼は、多様なクライアントのためにリッチ・インターネット・アプリケーションをビルドする傍ら、オープンン・ソース・プロジェクトに参加し、Agile Ajax ブログにも投稿しています。彼がプロジェクト・リーダーを勤める Really Simple History は、数千の Web サイトの実動コードで使われている Ajax の履歴およびブックマーク・ライブラリーです。



2008年 3月 04日

Ajax の手法は大規模な商用 Web アプリケーションの様相を一変させましたが、規模の小さな多くの Web サイトにはユーザー・インターフェース (UI) をまるごと一晩にしてリビルドするだけのリソースはありません。そのコストは、新しい機能が実世界のインターフェースの問題を解決し、ユーザー・エクスペリエンスを改善することで、妥当なものであることが証明されるはずです。この記事では、単純なモーダル・ウィンドウを使うことで、ポップアップ・ウィンドウを使わないようにし、さらにナビゲーションが脇道にそれて先に進まなくならないようにする方法を紹介します。Progressive Enhancement (漸進的な機能拡張) の原則を利用すれば、このような高度な UI 機能がサイトのアクセシビリティーや Web 標準遵守の妨げになることは決してありません。

この記事では、読者が HTML (Hypertext Markup Language) および CSS (Cascading Style Sheet) について十分理解していること、そして少なくとも JavaScript プログラミングと Ajax についての基礎知識があることを前提とします。サンプル・アプリケーションはクライアント・サイドのコードのみを使用して構築しているため、ここで紹介する手法はサーバー・サイドのどのアプリケーション・フレームワークにも適応できるはずです。サンプル・サイトを実行するには、ローカル・ホスト上で動作する基本的な Web サーバーが最低限必要になります。あるいは、ソース・コードを追いかけ、私の Web サーバーでサンプル・サイトの動作を確認するのでも構いません (「参考文献」に記載したリンクを参照)。

概念の紹介: Ajax によるサイトの改良

ユーザーを特定のルート、例えば製品の検索に始まり購入確定後の支払いに至るまで案内しなければならないのは、Web が誕生したときから必要なことでしたが、そこには未だに、途中でユーザーがそのルートから離れてしまう危険性があります。ナビゲーションのルートが長く複雑であるほど、ユーザーが途中で断念してしまう可能性は高くなります。そのためユーザーには十分な情報を提示して、プロセスに対する彼らの関心をつなぎとめておかなければなりません。

今回のタスク

この記事では、Web 1.0 のショッピング・サイトを Ajax の手法を使って改良する手順を案内します。サンプル・アプリケーションを「改良する前」と「改良した後」のソース・コードは「ダウンロード」セクションから入手できます。また、この 2 つのバージョンが実際に動作する様子を私の Web サーバー (「参考文献」を参照) で確認することもできます。Ajax の手法とベスト・プラクティスに加え、さらに Ajax が Progressive Enhancement の原則によってユーザー・エクスペリエンスをどのように改善するかについても説明します。

ウィキペディアでは Progressive Enhancement について、アクセシビリティー、セマンティック・マークアップ、そして外部スタイル・シートとスクリプト技術に重点を置く Web デザインの方針であると定義しています。Progressive Enhancement では Web 技術を階層形式で使用して、Web ページの基本コンテンツと機能には誰もが任意のブラウザーやインターネット接続を使ってアクセスできるようにする一方、より優れた処理能力や高機能のブラウザー・ソフトウェアを持つユーザーには同じページの拡張バージョンを提供します。

Web 1.0 の世界では、ショッピング・サイトでのユーザー・エクスペリエンスを簡素化する方法として、検索結果の表示から選択して購入を確定するまでの直線的なルートが構成されていました。ユーザーが購入を確定するまでのルートで提供される以上の情報を必要とする場合は、ナビゲーションを迂回して、情報が豊富な製品の詳細 (Product Detail) ページや比較 (Product Comparison) ページに進まなければなりません。このような「脇道」の問題は、購入を確定するまでのルートからユーザーを連れ出すことによって彼らにプロセスを投げ出すきっかけを与えてしまうことです。また、脇道を管理するのも簡単な話ではありません。ナビゲーション・ロジックでユーザーがこの袋小路に行き着くまでの情報を保管しなければならないためです。

この場合のソリューションとなりそうなのは、ポップアップ・ウィンドウです。補足情報をポップアップに表示させれば、メイン・ウィンドウでの直線的なステップバイステップのルートが中断されることはありません。しかし残念ながら、ポップアップ・ウィンドウは混乱を招き、邪魔になります。ナビゲーションの脇道よりは管理しやすいかもしれませんが、ポップアップ・ウィンドウも同じく、ユーザーがプロセスを途中で断念してしまう原因となりがちです。

幸い、脇道もポップアップも簡単に一切排除できる方法があります。それは、オープンソースの JavaScript ライブラリーです。この記事では、Ajax と DHTML (Dynamic HTML) の手法によって補足情報をツールチップやライトボックス、あるいはその他のモーダル・ウィンドウにレンダリングする方法を説明します。これらの要素はどのページにもそのまま挿入できるため、ホーム・ページから購入ページまでの簡単なステップバイステップのルートを維持する上で役立ちます。

サンプル・アプリケーションの紹介: Customize Me Now

この記事のサンプル・アプリケーションでは e-コマースに焦点を当てます。私はこの記事のため、ピザ、パッケージ旅行、あるいは投資ポートフォリオなどのさまざまな製品をユーザーがカスタマイズして購入できる Customize Me Now という名前の架空のショッピング・アプリケーションを作成しました。もちろん現実の世界では、これらの製品カテゴリーが同じサイトで扱われることはありませんが、ここでは多くのサイトが直面する複雑で現実的なナビゲーションの問題を説明するために一緒にしています。

まず Web 1.0 バージョンの Customize Me Now を紹介した後、このアプリケーションを Web 2.0 バージョンに改良します。たった 1 回 Ajax を呼び出すだけで補足情報を入手できることがわかると、 Web 2.0 バージョンにすることで、いかにナビゲーションのルートを簡素化できるかを納得できるはずです。この記事で説明する手法は、単純化の必要性とユーザー教育の必要性のどちらを取るかが問われるプロセスすべてに適応できます。Ajax を使用すれば、製品の構成、調査、一連のサービスへのサインアップ、あるいは単なる登録フォームの記入といったあらゆるプロセスを単純にすることが可能です。

手法の紹介: Ajax、ツールチップ、モーダル・ウィンドウ、ライトボックス

今となっては Ajax について紹介する必要はないでしょう。Ajax はWeb 開発の世界では至るところで使用されるようになり、目新しい技術ではなくなってきています。ここ数年の間、知識のあるプログラマーは、サーバーとの間を行き来することなく JavaScript コードを使って Web ページを少しずつ更新してきました。しかし、Ajax が主流になったのは、ひとえに xmlHttpRequest オブジェクト (元々は Windows® Internet Explorer® の拡張によるものでしたが、今では多種多様なブラウザーでサポートされるようになっています) を採用したおかげです。使用している Web アプリケーションがむしろデスクトップ・アプリケーションに近いと思える場合は必ずと言っていいほど、そこでは Ajax が動作しています。この記事では Ajax プログラミングの基礎について詳しく取り上げることはしませんが、Ajax の手法を用いた多数のオープンソース・ライブラリーを使用することになります。

Ajax UI ではよく、ツールチップ、ライトボックス、モーダル・ウィンドウを採用します。このようなしゃれた名前が付けられていますが、いずれも単なるポップアップ画面に過ぎません。つまり、別個のウィンドウで起動されるのではなく、ブラウザーのビューポート内に表示される画面です。ツールチップは一般的に小さなウィンドウで、大抵はユーザーがトリガー要素にマウスを移動させるとコンテキストに応じた内容を表示します。モーダル・ウィンドウはそれよりも大きいのが通常で、ほとんどの場合はクリック・イベントによってトリガーされます。ライトボックスは特殊なモーダル・ウィンドウです。このウィンドウでは半透明のオーバーレイによって、ウィンドウの元のコンテンツとモーダル・コンテンツが区別されます。この 3 つのコンテナーにはいずれも、さまざまなコンテンツを設定することができます。その例としては、DHTML の手法で非表示にしたインライン・コンテンツ、Ajax 呼び出しによってサーバーからプルされた新しいコンテンツ、iframe に挿入されたまったく別の文書などが挙げられます。人気の高い DVD レンタル・サービスである Netflix は、これらのインターフェース要素を実際に使用している顕著な例です。

ツールの紹介: jQuery、GreyBox、ThickBox、JTip、および jQuery フォーム

Ajax が主流となった 2005年以来、オープンソースのJavaScript ツールキットは増えています。そのそれぞれに強みと弱み、癖がありますが、なかでも特に優れたツールキットはブラウザーの違いに対応し、Ajax、DHTML、そして視覚効果のための (ブラウザーに依存しない優れた) アプリケーション・プログラミング・インターフェース (API) を提供します。ソリューションのなかには、Google Web Toolkit のようにサーバー・サイド Java™ コードを使って自動的にクライアント・サイドの JavaScript コードを生成するものもありますが、大多数のソリューションはネイティブ JavaScript ライブラリーです。

これらのネイティブ JavaScript ライブラリーのうち、この記事では jQuery を扱います。このライブラリーは 2006年に誕生して以来、その優れた API と JavaScript のコーディング量を少なくするという設計理念によって大きな支持を得ています。この jQuery を使用すれば、Ajax が使用されていない既存の Web 1.0 による Web サイトを、サーバー・コードや HTML マークアップ、そして CSS にほとんど変更を加えることなく Ajax で強化した Web 2.0 サイトに変身させることができます。既存の HTML 要素とサイトの振る舞いは、今お使いの JavaScript コードによって実行時にブラウザー内で変換されます。JavaScript が無効になっている場合、あるいはブラウザーが JavaScript をサポートしていない場合には、マークアップは通常通りに機能します。この Progressive Enhancement の原則のおかげで、皆さんの Web アプリケーションは可能な限り幅広いユーザーが確実に利用し続けられるようになります。モバイル機器や、身体的な障害を支援するソフトウェア、さらには 10 年前の Web ブラウザーからでさえも、引き続きアプリケーションを実行できるはずです。

jQuery を使うと Progressive Enhancement がサポートされるだけでなく、大規模で活気に満ちたプラグイン開発者たちのコミュニティーも利用できるようになります。JavaScript ツールキットの多くは考えられるあらゆる開発者のニーズを予測しようとしますが、jQuery が重点を置くのはあくまでも基本です。そのため、コア・ライブラリーは軽量のまま維持されており、追加機能はプラグインとしてオープンソース・コミュニティーで提供されています。そのうち、この記事では以下のプラグインを使用します。

  • ThickBox: Cody Lindley により開発
  • jQuery Forms: jQuery コミュニティーが共同で開発
  • JTip: Cody Lindley により開発され、jQuery コミュニティーが拡張
  • GreyBox: Amir Salihefendic により開発

アプリケーションの内容: Customize Me Now 1.0

以降のセクションでは Customize Me Now 1.0 を十分に理解してもらうため、そのユーザー・エクスペリエンスとソース・コードについて説明します。

ユーザー・エクスペリエンス

図 1 に、Customize Me Now の検索結果 (Search Results) ページと情報ポップアップ・ウィンドウを示します。この図から、ユーザーがカスタマイズしている製品に関して、このサイトがどれだけの情報を提供するかがわかるはずです。ユーザーが通る理想的なルートは検索結果からカスタマイズおよび購入の確定に直接進むルートですが、インターフェースにはこのルートからの迂回ルートがいくつか用意されています。このサイトでは従来のポップアップ・ウィンドウを使用して、各製品と製品オプションに関するコンテキストに応じた情報を提示します。例えば Pizza をクリックすると、このサイトが提供するピザ商品についての情報が表示されます。cheese をクリックすると、ピザに選択可能なチーズについての情報が表示されます。さらに、ユーザーはメーカーの Web サイトに進むこともできます。このサイトも同じく、ポップアップ・ウィンドウにレンダリングされます。

図 1. Customize Me Now 1.0 の検索結果ページ
Customize Me Now 1.0 の検索結果ページ

ユーザーが製品についてもっと詳しい情報を知りたいと思ったら、写真、記事、ユーザー・レビューなどと併せて各製品の詳細を説明する Product Details ページを表示することができます。さらに Product Comparison ページでは、製品を並べて表示、個々の製品同士を比較することもできます。このように、これらのリソース間のナビゲーションはいずれも複雑になっています。ユーザーは各製品をカスタマイズしなければならないため、途中の各ステップで Add to cart リンクを提供するだけでは事が済まないからです。サイトではユーザーにカスタマイズしてからカートに追加するよう促していますが、その一方、これらのステップを逆にして、一連のデフォルト・オプションを使ってカートに追加した後にカスタマイズできるようにもしています。

図 2 は、画面の関係を線で繋げた Customize Me Now 1.0 のサイト・マップです。この図には、ユーザーが通るルートはかなり複雑になる可能性があることが示されています。ほとんどの画面は、他の 2、3 の画面にリンクしているからです。

図 2. Customize Me Now 1.0 のサイト・マップ
Customize Me Now 1.0 のサイト・マップ

コード

Customize Me Now の機能デモ・コードには、クライアント・サイドのアセットである HTML CSS、JavaScript コード、画像ファイルしか記載されていません。現実の世界では、Microsoft® ASP.NET、Java 技術、Ruby on Rails、Django、または PHP といった大規模なサーバー・サイド・コンポーネントも当然あるはずですが、jQuery の優れた点はクライアント・サイドで完全に動作するため、サーバー・コンポーネントに関与することなく Ajax の手法を使ってユーザー・エクスペリエンスを簡素化できるという点です。したがって、今回のプロジェクトにはサーバー・サイドのコードが関係しないので、その詳細はデモ・コードに記載していません。HTML ファイルを開くときに、それが PHP テンプレートや JSP (JavaServer Pages™) ファイル、あるいはその他の HTML をブラウザーに送信するファイルである可能性があることだけを知っておいてもらえれば十分です。

Customize Me Now 1.0 アプリケーションのソース・コードをダウンロードしたら、いずれかのページのマークアップを調べてみてください。リスト 1 のようになっているはずです。

リスト 1. results.html 1.0 の HTML コード
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 <title>Customize Me Now: Search Results</title>
 <link rel="stylesheet" type="text/css" href="../css/customizemenow.css"/>
</head>

<body id="CMN">

 <!--[header goes here]-->

 <div id="main">
   <form method="GET" action="comparison.html">
     <h1>Search Results</h1>
     <div class="buttons">
       <input class="button" type="submit" name="submitTop" id="submitTop"
         value="Compare Selected Products" />
       or <a href="index.html">search again</a>
     </div>      
     <table class="searchResults">
       <thead>
         <tr>
           <th>Product</th>
           <th>Description</th>
           <th>Options</th>
           <th>Compare</th>
           <th>Actions</th>
         </tr>
       </thead>
       <tr>
         <td class="name">
           <a target="productPopup"
           href="productPopup.html?product=A">Pizza</a>
         </td>
         <td class="desc">
           A delicious Italian treat.<br />
           [<a href="detail.html?product=A">full product details</a>]
         </td>
         <td class="options">
           <ul>
             <li>
               <a target="optionsPopup"
               href="optionsPopup.html?product=A">crust</a>
             </li>
             <li>
               <a target="optionsPopup"
               href="optionsPopup.html?product=A">cheese</a>
             </li>
             <li>
               <a target="optionsPopup"
               href="optionsPopup.html?product=A">toppings</a>
             </li>
           </ul>
         </td>
         <td class="action">
           <input type="checkbox" target="productPopup" name="compareA"
           id="compareA" value="true" checked="checked"/>
         </td>
         <td class="action">
           <a class="button" href="customize.html?product=A">customize
           product</a>
           <a class="button" href="cart.html?product=A">add to cart with
           default options</a>
         </td>
       </tr>

       <!--[additional table rows go here]-->

     </table>
     <div>
     <div class="buttons">
       <input class="button" type="submit" name="submitBottom" id="submitBottom"
       value="Compare Selected Products" />
       or <a href="index.html">search again</a>
     </div>
   </form>
 </div>

 <!--[footer goes here]-->

</body>
</html>

アプリケーションを改良する方法

この記事では、まず Customize Me Now を改良してバージョン 2.0 にするプロセスを説明し、連載の第 2 回でさらにこのアプリケーションの開発を進めていきます。

jQuery およびプラグインをインストールする

Ajax の振る舞いをサイトに加えるための最初のステップは、使用するすべてのオープンソース・ライブラリーをダウンロードすることです。「ダウンロード」セクションからサンプル 2.0 アプリケーションをすでにダウンロードしている場合は、必要なライブラリーはすべてそこに含まれています。これらのライブラリーの最新バージョンを独自のアプリケーションに直接ダウンロードしたいのであれば、「ダウンロード」セクションからサンプルをダウンロードしなおしてください。

次に、jQuery とフォーム・プラグイン用の /js ディレクトリーを作成します。GreyBox、ThickBox、JTip にはいずれも固有のディレクトリーが必要であることに注意してください。画像、CSS ファイル、そして複数の JavaScript ライブラリーがバンドルされているこの 3 つのプラグインは、それぞれに固有のディレクトリー構造を前提とするからです。また、CSS と .js ファイルにリンクする際には、GreyBox の正しいルート・ディレクトリー・ポインターを設定するための簡単なスクリプト・ブロックを組み込む必要があります。このポインターは絶対ディレクトリー・パスでなければならないため、使用するコードではこの値を必要に応じて調整してください。この作業を終えると、HTML ファイルの head 要素はリスト 2 のようになっているはずです。

リスト 2. Customize Me Now 2.0 の header 要素
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

 <title>Customize Me Now: Shopping Cart</title>

 <!--customizemenow assets-->
 <link rel="stylesheet" type="text/css" href="../css/customizemenow.css"/>

 <!--jquery assets-->
 <script type="text/javascript" src="../js/jquery-1.2.1.min.js"></script>
 <script type="text/javascript" src="../js/jquery.form.js"></script>

 <!--thickbox assets-->
 <script type="text/javascript" src="../thickbox/thickbox.js"></script>
 <link rel="stylesheet" type="text/css" href="../thickbox/thickbox.css" />

 <!--jtip assets-->
 <script type="text/javascript" src="../jtip/scripts/jtip.js"></script>
 <link rel="stylesheet" type="text/css" href="../jtip/css/jtip.css" />

 <!--greybox assets-->
 <script type="text/javascript">
     /*this needs to be a non-relative reference*/
     var GB_ROOT_DIR = "/customizemenow/2/0/greybox/";
 </script>
 <script type="text/javascript" src="../greybox/AJS.js"></script>
 <script type="text/javascript" src="../greybox/AJS_fx.js"></script>
 <script type="text/javascript" src="../greybox/gb_scripts.js"></script>
 <link rel="stylesheet" type="text/css" href="../greybox/gb_styles.css" />

</head>

ThickBox および jQuery フォームを使って 2 次リンクをライトボックスに変換する

jQuery とそのプラグインは Progressive Enhancement の理念に従っているため、Ajax の機能を作り出すためのカスタム JavaScript コードはほとんど必要ありません。代わりに必要となるのは、既存の HTML タグに特定の属性を追加することです。JavaScript ライブラリーは DOM (Document Object Model) を解析してこれらの特殊な属性を見つけ、その属性を所有する要素に適切な振る舞いを追加します。jQuery では、すべてのマークアップがレンダリングされた時点で DOM を自動的に解析することによって、このコーディング・スタイルを可能にします。jQuery プラグインが裏で行っていることを覗いてみれば、いずれのプラグインもそのイベント・モデルをコア jQuery オブジェクトとその ready メソッドに委譲していることがわかります。

背景がわかったところで、早速、jQuery を使ってナビゲーションを簡素化する作業に取り掛かりましょう。購入の確定に至るまでのメインのルートに含まれないページを通常のページからライトボックス・ページに変換するには、ThickBox を使用します。まずは Product Details ページに手をつけて、ユーザーが「メインのルート」を離れずに、サイトのどこからでもこのページを表示できるようにします。

ThickBox を呼び出すのはわけありません。以下の特殊な属性を関連するそれぞれのリンクに追加すればよいだけの話です。

  • Thickboxclass 属性。この特殊な class 属性は、この要素に注意を払うよう ThickBox に通知します。
  • 以下のクエリー・ストリング値:
    • KeepThis=true および TB_iframe=true: この 2 つの値が、ThickBox に対してリンクを iframe が設定されたライトボックスにレンダリングするように指示します。
    • height=400: ThickBox ウィンドウの高さ (ピクセル単位)。これは任意の値にできますが、この例では値を 400 に設定します。
    • width=600: ThickBox ウィンドウの幅 (ピクセル単位)。これは任意の値にできますが、この例では値を 600 に設定します。

Product Details ページにはクエリー・ストリングを使ってすでに製品コードを渡しているため、ThickBox 値をアンパーサンド (&) を使用して既存の URL に追加するだけで済みます。これらの属性を Product Details リンクに追加し終わると、それぞれのポップアップ・リンクはリスト 3 のようになります。

リスト 3. ThickBox リンクの HTML コード
<a
href="detail.html?product=A&KeepThis=true&TB_iframe=true&height=400&width=600"
class="thickbox">product details</a>

Product Details ページへの対応はこれで済んだので、今度は Product Comparison ページを改良する番です。このページにアクセスする唯一の方法はフォームをサブミットすることです。つまり、ユーザーがチェック・ボックスを使って比較したい製品を選択します。このフォームをサブミットした結果を ThickBox でレンダリングするには、jQuery Forms が必要不可欠となります。このライブラリーは、複数のコンビニエンス・メソッドとイベント・フックを ajaxForm というオブジェクトにラップします。この ajaxForm と簡単なカスタム JavaScript コードを使用すれば、ThickBox の tb_show メソッドを直接呼び出すことができます。その方法として、リスト 4 のスクリプト・ブロックを results.html の先頭に追加してください。

リスト 4. フォームから ThickBox を呼び出すための JavaScript コード
<script type="text/javascript">

/*create a thickbox for our form submittal*/
//when the document is ready
$(document).ready(function() { 
 //wrap form#comparison in an ajaxForm object
   $('#comparison').ajaxForm({
   //intercept the submit event with a callback
   beforeSubmit:  function(formData, jqForm, options) {
     //serialize form data; append to the form action; tack on ThickBox params
     var URL = jqForm[0].action + "?" + $.param(formData);
     URL += "&KeepThis=true&TB_iframe=true&height=400&width=600";
     //call ThickBox directly
     var caption = null;
     var imageGroup = false
     tb_show(caption,URL,imageGroup);
     //cancel the form submission by returning false
       return false;
   }
 }); 
});

</script>

jQuery API の簡潔さを示すこのコード・ブロックでは、わずか数行のコードで HTML フォームの通常のサブミットをインターセプトし、代わりにカスタム JavaScript コードを実行しています。この手法を使えば、カスタム検証ロジックを実行してからでないとフォームをサブミットできないようにすることも、フォームをサブミットした後にカスタム・イベントをトリガーすることも可能です。そうすれば、フォームがまとめてサブミットされないようにして、フォームのサブミットによって生成されるはずの HTTP リクエストを、代わりに手動で「模造」し、フォームのターゲットを ThickBox ウィンドウにリダイレクトできるようになります。

ユーザーがこの舞台裏のアクションに気付くことはありません。ユーザーにわかるのは、フォームをサブミットするとモーダル・ウィンドウにその結果が表示されるということだけです。Product Comparison ページを確認した後、ユーザーが ThickBox ウィンドウを閉じれば、製品のカスタマイズそして購入の確定に至るルートにに再び戻ることができます。

ThickBox を使って Product Details ページと Product Comparison ページをレンダリングする上で唯一の問題となるのは、ThickBox ウィンドウに表示するにはこれらのページの幅が大きすぎるという点だけです。ThickBox に渡す幅と高さの値を変更することはできますが、ユーザーのビューポートがそれよりも小さい場合を考えてみてください。ThickBox がウィンドウ全体を覆い尽くしたり、ましてやビューポートに収まりきらないという事態は避けなければなりません。そこで、inlineclass を body タグに追加して単純に details.html と comparison.html のスタイルを再設定し、その上でリスト 5 の CSS 宣言を customizemenow.css に追加します。

リスト 5. ThickBox の CSS
#CMN #main.inline {
 width: 600px;
}

モーダル・ウィンドウを実装するための最後のステップは、Product Details ページと Product Comparison ページの要素でユーザーに操作させたくない要素を操作できないようにすることです。これらのページの目的は現在、情報の表示専用となっているので、アクション・リンクやボタンをページに組み込む必要はありません。また、ナビゲーター・バーやその他のクロームを表示する必要もありません。

これを実現する方法は何通りかあります。例えばこれらの要素をページからただ単に削除するという方法がありますが、こうすると Progressive Enhancement の方針が台無しになってしまいます。つまり、JavaScript を有効にしたくないユーザーがページから出られなくなったり、あるいは購入を確定するプロセスに進めなくなったりするという結果になるのがおちです。また、クエリー・ストリング・パラメーターをリンクに追加することで、サーバー・サイドのフレームワークが異なるテンプレートを使ってこれらのページをレンダリングするようにするという方法も考えられます。現実の世界ではおそらくこの方法を使うでしょうが、他にも有効な対処方法があります。それは、クライアント・サイドのコードのみに依存し、昔ながらの <noscript> タグを使うという方法です。<noscript> タグにそれぞれの要素をラップすれば、JavaScript 以外のユーザー・エージェント、つまり目的とするユーザーにしか見えない要素になります。

ヘッダーとフッターの最終的な HTML コードは、リスト 6 に記載したコードのようになります。

リスト 6. Customize Me Now 2.0 ナビゲーションの HTML コード
<noscript>
 <div id="footer" class="nav">
   <<ul>
     <li><a href="index.html">search&/a></li>
     <li><a href="results.html">results</a></li>
     <li><a href="detail.html">details</a></li>
     <li><a href="comparison.html">compare</a></li>
     <li><a href="customize.html">customize</a></li>
     <li><a href="cart.html">cart</a></li>
     <li><a href="checkout.html">checkout</a></li>
     <li class="last"><a href="confirm.html">confirmation</a></li>
   </ul>
 </div>
</noscript>

リスト 7 は、Product Details ページの main コンテンツ <div> の HTML コード例です。

リスト 7. details.html 2.0 の HTML コード
<div id="main" class="inline">

 <form method="GET" action="customize.html">
   <input type="hidden" name="product" id="product" value="A" />

   <h1>Pizza: Product Details</h1>

   <noscript>
     <div class="buttons">
       <input class="button" type="submit" name="submitTop" id="submitTop"
       value="Customize Now" />
       or <a href="cart.html?product=A">add to cart with default
       options</a>
     </div>
   </noscript>

   <!--[content goes here]-->

   <noscript>
     <div class="buttons">
       <input class="button" type="submit" name="submitBottom" id="submitBottom"
       value="Customize Now" />
       or <a href="cart.html">add to cart with default options</a>
     </div>
   </noscript>

 </form>

</div>

リスト 8 は、Product Comparison ページのメイン・コンテンツの <div> の HTML コード例です。

リスト 8. comparison.html 2.0 の HTML コード
<div id="main" class="inline">

 <h1>Product Comparison</h1>

 <table class="productComparison">
   <thead>
     <tr>
       <th>Product</th>
       <th>Pros</th>
       <th>Cons</th>
       <noscript>
         <th>Actions</th>
       </noscript>
     </tr>
   </thead>
   <tr>
     <td class="name">
       <a class="jTip" name="About Pizza" id="pizza" target="productPopup"
       href="productPopup.html?product=A">Pizza</a>
     </td>
     <td class="pros">
       <ul>
         <li>Great flavor.</li>
         <li>Low cost.</li>
         <li>Fun with friends.</li>
       </ul>
     </td>
     <td class="cons">
       <ul>
         <li>Can make you fat.</li>
         <li>Not very nutritious.</li>
       </ul>
     </td>
     <noscript>
       <td class="action">
         <a class="button" href="customize.html?product=A">customize
         product</a>
         <a class="button" href="cart.html?product=A">add to cart with
         default options</a>
       </td>
     </noscript>
   </tr>

   <!--[additional table rows here]-->

 </table>

</div>

developerWorks の Ajax リソース・センター
Ajax resource center にアクセスしてください。ここは、無料のツール、コード、そして Ajax アプリケーションの開発に関する情報を用意されたワンストップ・ショップです。また、Ajax のエキスパートである Jack Herrington がホストする活発な Ajax コミュニティー・フォーラムは、あなたが今まさに探している答えを持っているかもしれない開発者仲間と交流する手段となります。

これまでの作業の結果を確認するには、Customize Me Now 2.0 のSearch Results ページをブラウザーに表示して、そこから Product Details ページまたは Product Comparison ページを起動してください。すると、図 3 のようなページが表示されるはずです。

図 3. ThickBox の動作
ThickBox の動作

まとめ

この記事では盛り沢山の内容を説明しましたが、Ajax の手法とベスト・プラクティスの紹介としてはまだ序の口です。連載第 2 回では引き続きナビゲーションを改良するため、JTip を使ってポップアップ・リンクをツールチップに変換し、さらに GreyBox を使ってオフサイト・リンクをライトボックスに変換します。そして最終的には、このサンプル・アプリケーションの背後にある主要なすべての概念を見直し、アプリケーションの改良によってユーザー・エクスペリエンスがどのように改善されたかを検討します。先に作業を進めたいという方は、Customize Me Now 2.0 のソース・コードをさらに詳しく調べて、Web ブラウザーでその動作を確かめてみてください。


ダウンロード

内容ファイル名サイズ
Source code for the original demo appcustomizeOnePointZero.zip24KB
Source code for the retrofitted demo appcustomizeTwoPointZero.zip88KB

参考文献

学ぶために

  • Customize Me Now 1.0 の動作は、私の Web サイトで確認できます。
  • すべての変更を加えた後の Customize Me Now 2.0 の動作を私の Web サイトで確認してください。
  • jQuery の詳細について学んだり、その他のプラグインを探すには jQuery の Web サイトにアクセスしてください。
  • Learning jQuery Web サイトから jQuery コミュニティーに加わって、チュートリアルやフォーラムにアクセスしてください。
  • Web 2.0 開発のツールと情報が満載の developerWorks Web development ゾーンにアクセスしてください。
  • developerWorks Ajax resource center には、Ajax 関連の記事が次々と追加されています。Ajax アプリケーションを今すぐ始めるのに役立つ資料もここから入手できます。
  • jQuery を使って Ajax 開発を単純化する」(Jesse Skinner 著、developerWorks、2007年4月10日) を読んで jQuery の設計理念とその特徴と機能を理解してください。この記事では、いくつかの一般的な Ajax タスクも実行し、プラグインを使って jQuery を拡張する方法も学べます。
  • Ajax と XML: Ajax を適用したライトボックス」(Jack Herrington 著、developerWorks、2007年9月25日) では、Prototype JavaScript ライブラリーを使ってライトボックスとツールチップを実装する方法を紹介しています。
  • jQuery の入門書として『Learning jQuery』を読んでください。
  • jQuery in Action』も jQuery の参考資料として役立つ本です。
  • 一般的な jQuery 資料としては『jQuery Reference Guide』が頼りになります。
  • jQuery とその他の UI については、Brian Dillard のブログ、Agile Ajax を調べてください。
  • developerWorks technical events and Webcasts で最新情報を入手してください。
  • テクノロジーのブックストアで、この技術やその他の技術に関する本を探してください。

議論するために

  • developerWorks コミュニティーに参加してください。developerWorks ブログに参加してください。

その他のダウンロード

  • コードサンプル: jQuery (このオープンソースの Ajax ツールキットが Ajax 機能の基盤となります。この記事を書いている時点での最新バージョンは 1.2.1 です。)
  • コードサンプル: JTip (この jQuery プラグインを使うと、情報を表示するポップアップをブラウザーに依存しない単純なツールチップに置き換えられます。)
  • コードサンプル: ThickBox (このプラグインを使用すると、Product Details ページと Product Comparison ページをモーダル・ウィンドウにロードすることができます。この記事のサンプル・アプリケーションで使用しているのはバージョン 3.1 です。)
  • コードサンプル: jQuery Forms (Product Comparison ページにはフォーム・パラメーターが必要なため、このページを ThickBox でレンダリングするには多少のカスタム JavaScript コードを作成しなければなりませんが、幸い、このユーティリティー・ライブラリーがその作業の大部分を代わりに引き受けてくれます。)
  • コードサンプル: GreyBox (この jQuery プラグインでは、メーカーの Web サイトを単純で見栄えのいいライトボックスにリンクすることができます。サンプル・アプリケーションで使用しているのはバージョン 5.53 です。)

コメント

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, XML
ArticleID=298685
ArticleTitle=Ajax による改良: 第 1 回 Ajax と jQuery で既存のサイトを改良する
publish-date=03042008