目次


jQuery を扱う

第 1 回 ブラウザーでデスクトップ・アプリケーションを実現する

コア関数、要素の選択、そして結果のトラバース

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: jQuery を扱う

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:jQuery を扱う

このシリーズの続きに乞うご期待。

はじめに

jQuery は Web 開発者に好んで使われるライブラリーとして他の JavaScript ライブラリーとは一線を画しています。クライアント・サイドの開発を容易にして RIA (Rich Internet Application) を素早く効率的に作成する方法を求めるプログラマーにとって、jQuery は急速に第一の選択肢となりつつあります。RIA の使用が、今後ますます広まっていくにつれて、そうした RIA の開発を補助するための JavaScript ライブラリーを使用する機会も増えていくことでしょう。RIA の (大まかな) 定義は、ブラウザーを通して実行されるアプリケーションでありながら、CSS、JavaScript、Ajax を組み合わせることで、デスクトップ・アプリケーションで作業しているかのような使用感を実現するもの、とされています。Firefox や Internet Explorer、Safari の最近のリリースや、Google から新しくリリースされた Chrome ブラウザーなどに追加されている最新機能では、各ブラウザー内部の JavaScript エンジンを高速化することに焦点が当てられています。その最大の目的は、近い将来使われるようになるとブラウザー・メーカーが思い描いているような RIA の実現に貢献することです。これらのブラウザー・メーカーは Web ページが何万行もの JavaScript コードを含むようになると想定しており、そのため出発点として利用できるような、成熟した、そしてバグのないライブラリーの重要性が非常に高まっています。

つまり Web アプリケーションの将来が、Web アプリケーションであることを意識させない、リッチな没入型インターフェースの方向に進んでいるのに伴い、Web 開発者は次第に、その開発作業を楽にするツールを求めるようになっています。現在、世の中にはいくつかの JavaScript ライブラリーがあり、それぞれ独自の強みと弱みを持ち、そしてそれぞれに愛好者と批判者がいます。ここでは、機能に関してどれが他よりも優れているかを議論するつもりはありません。最終的には、機能の優劣はあまり大した問題ではなく、最も重要なことは、どのライブラリーが他のライブラリーよりも多く使われるか、つまりよく使われるということが重要だからです。最もよく使われている 4 種類の JavaScript ライブラリーに関する Google Trends のグラフを見てください (図 1)。過去 6 カ月から 8 カ月の間、JavaScript ライブラリーの選択肢としては jQuery が支配的になっており、またその成長も著しいことが明らかです。

図 1. よく使われるJavaScript ライブラリーに関する Google Trends
よく使われるJavaScript ライブラリーに関する Google Trends
よく使われるJavaScript ライブラリーに関する Google Trends

雇用市場にも、jQuery が最もよく使われる JavaScript ライブラリーとして台頭してきていることが表れています。あまり科学的な見方ではありませんが、Monster.com においては、「jQuery」関係の求人が 113 件ある一方、YUI、ExtJS、mootools 関係では、それぞれ 67 件、19 件、13 件の求人数にとどまっています。

今回は jQuery に関するシリーズの第 1 回として、jQuery の構文とセットアップ方法、そして関数の呼び出し方について説明します。この記事の後の方のセクションでは、このライブラリーのコア関数について説明し、さらに jQuery の強力な選択機能とフィルターを使うことで容易かつ単純に DOM をトラバースできることを説明します。今後の記事では、CSS の操作、フォームの制御、テキストの変更、Ajax の単純化、そして (見た目に楽しい) アニメーションなどについて説明します。jQuery で最も興味深い機能の 1 つがプラグイン・アーキテクチャーであり、このアーキテクチャーによって開発者は jQuery に機能を追加することができます。最終回の記事では、RIA 開発プロセスを完成させるために利用可能な強力なプラグインを多数紹介します。

このシリーズの記事は、JavaScript の構文や CSS の構文、そして DOM の構文に関する知識を持っている人を対象にしています。このシリーズの記事を読む前にこれらの構文について復習したい場合には、この記事の「参考文献」のセクションに挙げた W3Schools へのリンク (訳注: リンク先は英語です) を参照することを強くお勧めします。

基本事項

jQuery の面白いところに入る前に、まずは基本的なこと、つまりどのようにインストールし、手始めに何をしなければならないか、などを理解する必要があります。まず「ダウンロード」セクションに用意した jQuery ライブラリーをダウンロードし、そして他の外部 JavaScript ファイルに対してリンクする場合と同じように、このライブラリーにリンクします。

リスト 1. コードの中に jQuery をインストールする
<script type="text/javascript" src="jquery.js"></script>

jQuery は DOM オブジェクトの呼び出しや操作を行います。そのため、文書でページ上のすべての要素のロードが終わる前に DOM オブジェクトを JavaScript コードの中で即座に操作すると問題が起こります。逆に、ページ上のすべてのもの (すべての画像やバナー広告、分析コード、YouTube ビデオのプレビューなど) がロードされるまで待たないと jQuery コードを呼び出せないという事態も避けたいものです。幸いなことに、中間的な方法を使用すれば、文書がページ上の全要素のロードを終了した状態で (ただしすべての画像やリンク、描画は完了する前に) 安全かつエラーを起こさずに jQuery コードを呼び出すことができます。これを再度強調するために別の言い方をすると、すべての jQuery コードは、ページ上の this 関数の中、もしくは独自の関数の中になければなりません。関数の中に入っていない jQuery コードは、JavaScript コード・セクションの中に書いてはならないのです。

リスト 2. jQuery の関数を適切に呼び出す方法
// Incorrect
<script language=JavaScript>
   $("div").addClass("a");
</script>

// Correct
$(document).ready(function(){
   $("div").addClass("a");
 });

// - or -

$(document).ready(function(){
   myAddClass();
 });

function myAddClass()
{
   $("div").addClass("a");
}

また、便利なヒントを 1 つ追加しておきます。それは、ページ上では必要なだけ document.ready() 関数を使うことができ、これらの関数は連続して呼び出されるということです。これを覚えておくと便利な場合として、モジュールを使ってページを動的に作成しようとする際、各モジュールが jQuery による独自のサポート・コードを持っている場合 (例えば PHP ページが、多数のより小さな PHP ページ・スニペットで構成される場合など) があります。

jQuery で最も興味深い特徴の 1 つが「Chainability (連鎖性)」です。jQuery では、コードの読みやすさを改善し、またコーディングを容易にするために、一連の関数を連鎖させて呼び出すことができます。ほとんどすべての jQuery 関数は jQuery オブジェクトを返すので、その返されたオブジェクトに対してさらに他の関数を呼び出すということを何回でも繰り返し、それらの関数を連鎖させて 1 つの完全な jQuery コマンドにすることができるということです。これは Java における String クラスのようなものです (Java の String クラスでは、いくつかの関数が 1 つの String オブジェクトを返すことで複数の関数を 1 行にまとめることができます)。

リスト 3. jQuery の Chainability
String man = new String("manipulated").toUpperCase().substring(0,5).toLowerCase();

$("div").addClass("a").show().text("manipulated");

最後に、jQuery を扱う際、あるいは他のどの JavaScript ライブラリーを扱う際にも覚えておく必要のある注意点として、JavaScript ライブラリー同士が必ずしもうまく動作するとは限らない、ということが挙げられます。言い換えると、複数のライブラリーを扱う際にはそれら複数のライブラリーで変数「$」が使われるため、「$」呼び出しでどのライブラリーを参照すべきなのかが、エンジンには判別できないということです。これを示す最適な例が、prototype.js が組み込まれている CakePHP のライブラリーです。このライブラリーが使われているページでそのまま jQuery を使おうとするとエラーが起こります。この問題に対応するために、jQuery には「$」変数を別の変数にマッピングする方法が用意されています (リスト 4)。

リスト 4. jQuery での競合の解決
j$ = jQuery.noConflict();
j$("div").addClass("a");

要素の選択

jQuery のすべての基底に横たわるのは、ページ上の特定の要素を選択して操作を行える能力です。ある意味で、jQuery ライブラリーはそうした選択や操作を目的として構築されていると言えます。通常の HTML ページ上には無数の選択肢が含まれている中で、そのページ上で作業対象としたい要素を素早く効率的に選択する方法が必要であり、必要なものだけを (過不足なく) 選択できなければなりません。ご想像の通り、jQuery には、ページ上のオブジェクトを見つけて選択できる、強力な選択メソッドが用意されています。また jQuery では選択のための独自の構文が採用されており、その構文は非常に容易に学ぶことができます。

(以下に示す例の多くにおいて、次回の記事で説明する関数が使われていますが、そう複雑なものではないので、そうした関数が何をするためのものかはご理解いただけるはずです。)

根本的に、jQuery における選択プロセスは実際には巨大なフィルター・プロセスであり、ページ上のすべての要素はコマンドの中で提供されるフィルターにかけられます。そして条件に一致する 1 つのオブジェクトが返されるか、あるいは条件に一致するオブジェクトの配列が返されるので、この配列に対してトラバースを行います。

最初に挙げる 3 つの例は、おそらく最も一般的に使われるものです。この 3 つの例では、それぞれ HTML タグ、ID、あるいは CLASS を使ってオブジェクトを検索します。

HTML による選択

ページの中で条件に一致するすべての HTML 要素の配列を取得するためには、単純にその HTML タグそのものを、中括弧を付けずに jQuery の検索フィールドに渡します。この方法は、オブジェクトを見つける上ではスマートではないものの手軽であり、また汎用の HTML 要素に属性を追加する上では便利です。

リスト 5. HTML による選択
// This will show every <div> tag in the page.  Note that it will show 
// every <div>, not the first matching, or the last matching.  
// Traversing Arrays is discussed later in the article.
$("div").show();

// This will give a red background to every <p> tag in the page.
$("p").css("background", "#ff0000");

ID による選択

適切にページを設計するには、ページ上のすべての ID が一意に決まるようにする必要がありますが、この規則は時々 (意図的に、あるいは誤って) 破られます。ID による選択を使用する場合、jQuery は条件に一致する最初の要素のみを返しますが、これは jQuery がそのページは適切な設計に従っているものと想定しているためです。ある 1 つのタグを同じページ上のいくつかの要素に追加したい場合には、CLASS タグの使用が適切な選択肢と言えます。

リスト 6. ID による選択
// This will set the innerHTML of a span element with the id of "sampleText" to "Hi".  
// Note the initial "#" in the command.  This is the syntax used by jQuery to search 
// for IDs, and must be included.  If it is excluded, jQuery will search for the HTML
// tag instead, and with no <sampleText> tags on a page, will ultimately do
// nothing, leading to frustrating and hard-to-find bugs (not that that has ever 
// happened to me of course).

$("#sampleText").html("Hi");

CLASS による選択

クラスは ID と非常に似ていますが、クラスはページ上の 1 つの要素に対しても複数の要素に対しても使える点が異なります。従って、ページ上の 1 つの ID に対しては 1 つの要素しか持つことができませんが、同じ CLASS を使う要素はページ上に多数持つことができます。このことから、1 つの CLASS 名を渡すだけで、ページ上の多種多様な要素全体に対して柔軟に関数を実行することができます。

リスト 7. CLASS による選択
// This will create a red background on every element on the page with a CLASS of 
// "redBack".  Notice that it doesn't matter which HTML element this "redBack" 
// CLASS tag is attached to.  Also notice the period in the front of the query
//  term -- this is the jQuery syntax for finding the CLASS names.

$(".redBack").css("background", "#ff0000");

<p class="redBack">This is a paragraph</p>
<div class="redBack">This is a big div</div>
<table class="redBack"><tr><td>Sample table</td></tr></table>

検索条件を組み合わせる

上記の 3 つの検索条件、そして下記に紹介するすべてのフィルターは、1 つの検索の中で組み合わせることができます。検索条件を「,」で区切って検索を行うと、その検索に含まれる用語群に一致するものすべての和集合が返されます。

リスト 8. 検索条件を組み合わせる
// This will hide every <p>, <span>, or <div>.
$("p, span, div").hide();

その他のフィルター

上記の 3 つは確かに jQuery で最もよく使われる検索パラメーターですが、ページ上で目的の要素を素早く見つけるのに役立つ検索パラメーターは他にもたくさんあります。そうしたフィルターは、すべて「:」で始まり、それらが jQuery の検索用語におけるフィルターであることを示しています。これらのフィルターは個別に検索条件として使用することもできますが、基本的には上記の 3 つの検索条件と組み合わせて使うように設計されており、それによって検索条件を微調整し、目的の要素を見つけられるようになっています。

リスト 9. その他のフィルター
// This will hide every <p> tag on a page
$("p").hide();

// This will hide the first element on a page, no matter its HTML tag
$(":first").hide();

// Notice how these can be used in combination to provide more fine tuning of 
// search criteria.  This will hide only the first <p> tag on a given page.
$("p:first").hide();

検索要素としては、さまざまなフィルターを使うことができます。ここではすべてのフィルターを取り上げるわけではありませんが (すべてのフィルターを取り上げるのは結局のところ API ページの役割です)、一部のフィルターはページを扱う上で、また要素を検索する上で、非常に便利です。

ここでは非常に重要ないくつかのフィルターとして、 Selection パッケージの中にある、フォーム要素用のフィルターについて説明します。今日の RIA アプリケーションの焦点は、サーバーとの間で情報の収集と送受信を実現する、フォームと、フォームに含まれる要素 (テキスト・フィールド、ボタン、チェック・ボックス、ラジオ・ボタンなど) にあるようです。RIA におけるフォームやその要素の重要性から、それらを扱うためのフィルターは、今日あるような Web アプリケーションのタイプで jQuery を使用する際には特に重要となります。

これらのフィルターは、この記事でこれまで説明した他のフィルターと同じように動作し、またフィルターであることを示すための「:」という文字が前に付きます。また、他の検索フィルターと組み合わせ、より詳細な検索を行うことができます。例えば、「:text」という検索フィルターを使った場合にはページ上のすべてのテキスト・フィールドが返されます。また「.largeFont:text」という検索フィルターを使った場合には、ページ上で「largeFont」クラスに属するテキスト・フィールドのみが返されます。このようにして、フォーム要素をさらに調整したり操作したりすることができます。

またフォーム用のフィルターには、要素の個々の属性も含まれるということも、開発者として知っておくとよいでしょう。例えば「:checked」や「:disabled」、「:selected」などによって、特定の検索における検索条件をさらに細かく設定することができます。

検索結果のトラバース

さて、ページ上のすべての要素に対する検索方法とフィルター方法を学んだので、次は検索の結果得られた要素をトラバースしてアクションを実行するための効率的な方法が必要です。当然ながら、jQuery には、これらの検索結果をトラバースするための方法がいくつか用意されています。

第 1 の、そして最もよく使われるトラバースの手法は、each() 関数です。これはプログラムの面で見れば「for ループ」と同じであり、各要素をループして、繰り返しごとに要素をインクリメントします。さらに、ループの中の各要素を「this」(通常の JavaScript 構文を使う場合) または $(this) (jQuery のコマンドの中で使う場合) を使って参照することができます。

次の例を見てください。

リスト 10. each ループ
// Will loop through each <p> tag on the page.  Notice the use of the
// inline function here -- this is analogous with the anonymous classes in Java.
// You can either call a separate function, or write an inline function like this.

var increment = 1;
$("p").each(function(){

    // now add a paragraph count in front of each of them.  Notice how we use the
    // $(this) variable to reference each of the paragraph elements individually.

    $(this).text(increment + ". " + $(this).text());
    increment++;
});

検索結果は配列に保存されるため、どんなプログラミング言語でどんなデータ・オブジェクトを扱う場合もそうであるように、そういった配列を扱うための関数があります。ここでは、ある検索結果の長さを得るためには、その配列に対して $().length を呼び出せるようになっています。配列をトラバースするための他の関数はリスト 11 に示すとおりであり、これらの関数は他のプログラミング言語における配列のトラバースと同様のものとなっています。

リスト 11. その他の配列関数
// the eq() function lets you reference an element in the array directly.  
// In this case, it will get the 3rd paragraph (0 referenced of course) and hide it
$("p").eq(2).hide();

// The slice() function lets you input a start and an end index in the array, to 
// create a subset of the array.  This will hide the 3rd through 5th paragraphs on the
// page
$("p").slice(2,5).hide();

配列をトラバースするためのこうした関数の他に、jQuery には検索用語に指定した要素のすぐ近くにネストされた要素を発見するための関数が用意されています。なぜこれが便利なのでしょう。皆さんもご存じのように、画像の隣にテキスト・ラベルを埋め込んだり、あるいはフォーム要素の隣にエラー・メッセージを埋め込んだりしたいことがよくあるものです。これらのコマンドを使うことで、特定のフォーム要素を検索し、見つかった要素のすぐ隣にエラー・メッセージを配置することができます (そのためには、見つかった要素の次の要素として span タグを追加し、その中にエラー・メッセージを置きます)。リスト 12 はこうした設計の一例です。

リスト 12. next() 関数の例
<input type=text class=validate><span></span>

function validateForm()
{
    $(".validate:text").each(function(){
    if ($(this).val()=="")
    //  We'll loop through each textfield on the page with a class of "validate"
    //  and if they are blank, we will put text in the <span> immediately afterwards
    //  with the error message.

        $(this).next().html("This field cannot be blank");
});
}

ここまでの内容を総合する

ここまでに学んだことを総合するとどんなことができるのかを知るために、この記事に含まれているデモ・アプリケーションを見てみましょう (「ダウンロード」セクションを参照)。

先に、このデモ・アプリケーションの基本的な内容を簡単に説明しておきます。このシリーズの記事では全体を通してこのデモ・アプリケーションを使っていきます。その理由は、さまざまな jQuery の例が使われており、また Web メール用の RIA という、ほとんどの人にとってなじみのあるアプリケーションであるからです。このデモ・アプリケーションは簡単なメール・クライアントであり、jQuery を利用することによって、あたかも実際にはデスクトップ・アプリケーションである E メール・クライアントを操作しているかのような感覚をユーザーに与えます。このシリーズの最終回の記事まで読み終えると、この簡単なアプリケーションでそうしたルック・アンド・フィールをユーザーに提供できること、そして理想的には、そのための開発作業が jQuery を使うことでいかに容易になるかを理解できるはずです。

この記事では、Web メールのテーブルの一番上の左側に表示されるチェック・ボックス「Select All/Deselect All (すべてを選択/すべての選択を解除)」(図 2 の中で強調表示してあります) に焦点を当てます。このチェック・ボックスが選択されると、その列にあるすべてのチェック・ボックスが選択され、そしてこのチェック・ボックスが選択解除されると、その列にあるすべてのチェック・ボックスが選択解除されます。

図 2. 「Select All (すべてを選択)」チェック・ボックス
Select All Check box
Select All Check box
リスト 13. ここまでに学んだ内容を総合する
<!-- The first step is creating the Select All checkbox itself.
we give it a unique ID on the page -->

<input type=checkbox id=selectall>

<!-- The next step is giving each of the rows their own checkbox.
we put each row's checkbox into the 'selectable' class, since there can be many rows,
and we want each of the rows' checkboxes to have the same behavior. -->

<input type=checkbox class=selectable>

<!-- The final step is bringing it all together with some jQuery code. -->

// remember that all jQuery setup code must be in this document.ready() function, 
// or contained within its own function in order to function correctly.

$(document).ready(function(){
   // We use the jQuery selection syntax to find the selectall checkbox on the page
   // (note the '#' which signifies ID), and we tell jQuery to call the selectAll()
   // function every time someone clicks on the checkbox (we'll get to Events in a
   // future article).

   $("#selectall").click(selectAll);
});

// This function will get called every time someone clicks on the selectall checkbox
function selectAll()
{
    // this line determines if the selectall checkbox is checked or not.  The attr()
    // function, discussed in a future article, simply returns an attribute on the
    // given object.  In this case, it returns a boolean if true, or an undefined if
    // it's not checked.

    var checked = $("#selectall").attr("checked");

    // Now we use the jQuery selection syntax to find all the checkboxes on the page
    // with the selectable class added to them (each row's checkbox).  We get an array
    // of results back from this selection, and we can iterate through them using the
    // each() function, letting us work with each result one at a time.  Inside the
    // each() function, we can use the $(this) variable to reference each individual
    // result.  Thus, inside each loop, it finds the value of each checkbox and matches
    // it to the selectall checkbox.

    $(".selectable").each(function(){
       var subChecked = $(this).attr("checked");
       if (subChecked != checked)
          $(this).click();
    });
}

まとめ

jQuery は Web アプリケーション開発のコミュニティーで最もよく使われる JavaScript ライブラリーになりつつあります。今後より一層 RIA が広まるにつれ、jQuery の重要性はますます高まるでしょう。さまざまな会社が内部アプリケーションをオンラインへとマイグレートし、また日常的に使用するデスクトップ・アプリケーション (ワード・プロセッサーやスプレッドシートなど) をオンラインに移行する中で、その開発を容易にし、またクロスプラットフォームのサポートを約束する JavaScript ライブラリーは、アプリケーションを構築する際に選択される技術のひとつとなるはずです。

jQuery に関するシリーズの第 1 回であるこの記事では、jQuery の構文、独自の JavaScript コードの中で jQuery を適切に使う方法、そして他のライブラリーと一緒に使う場合の落とし穴を避ける方法について紹介しました。また jQuery のすべての機能の基となる、検索と選択のための構文を紹介しました。この構文によって、任意のページ要素を簡単に素早く見つけることができ、またそれらの要素に対してアクションを実行することができます。この記事ではまた、そうした検索の結果をナビゲートし、そこに含まれる要素に対して個々にアクションを実行する方法についても説明しました。jQuery の持つこの 2 つの側面は、このシリーズの今後の記事の基本となり、また皆さんが作成する jQuery コードのための基本となります。

最後に、Web メール用の RIA であるデモ・アプリケーションを紹介しました。今回は、この記事で学んだ jQuery を使ってチェック・ボックス Select All/Deselect All を作成し、そしてわずか数行のコードによって、多くの Web サイトに見られる一般的なウィジェットを作成できることを学びました。

このシリーズの次回の記事では、このサンプル Web アプリケーションに少し対話動作を追加します。そして、ページ・イベント (要素のクリック、ボタンのクリック、コンボ・ボックスでの選択など) を処理する方法、ページ上の要素から値を取得する方法、ページ上の標準的な CSS を変更し、ページをリロードせずに色や配置などを変化させる方法などを学びます。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development
ArticleID=343432
ArticleTitle=jQuery を扱う: 第 1 回 ブラウザーでデスクトップ・アプリケーションを実現する
publish-date=09092008