さまざまなプラグイン
jQueryがこれほど人気を得た主な理由の1つはプラグインにあります。これにはjQueryが非常に単純なプラグインAPIを備えていることが関係しています。マッチセットに対して実行可能なあらゆる関数をホストするjQuery.fnプロパティがあります。単に新しい関数をjQuery.fnに実装すれば、jQueryの組み込み関数と同じように動作する新しいマッチセット関数を作成できます。次に示すのは非常に単純なpulseプラグインです。これは要素をある程度までフェードアウトさせてから元どおりにフェードインさせることで、要素を脈動させるような表現を作ります。
$.fn.pulse = function(time)
{
if (!time)
time = 2000;
// this == jQuery instance
this.fadeTo(time,0.30, function() {
$(this).fadeTo(time,1);
});
return this; // return jQuery
}
こうすると、jQueryのインスタンスを使用し、そのインスタンスに対してpulse関数を使用するだけで、マッチした要素を脈動させることができます。例えば、前にグリッドに新しいアイテムを追加しましたが、次のように書けば、このアイテムをフェードインさせる代わりに脈動させることができます。
row.insertBefore(
"#gdEntries>tbody>tr:nth-child(2)")
.css("background", "paleyellow")
.pulse(2000);
このプラグインはマッチした複数の要素に対しても有効です。次の例ではグリッド内の偶数番目の行が脈動します。
$("#gdEntries>tbody>tr")
.filter(":even")
.addClass("gridalternate");
.pulse(1000);
プラグインはjQueryマッチセットであるthisポインタを受け取ります。そのため、プラグインコードでさらに機能を適用することができます。プラグインに独自の戻り値がない場合は、その関数をチェイン可能にするために、jQueryの元の結果セットを返すべきです。例えば次のようにします。
$("#gdEntries>tbody>tr")
.filter(":even")
.addClass("gridalternate");
.pulse(1000)
.addClass("small");
このプラグインは単純化されています。一般的には、若干のセットアップデータと、マッチした要素をループして個別に操作するためのロジックが必要です。では、もう少し現実的なプラグインを示しましょう。次のプラグインはブラウザウィンドウまたは別の要素の内部で要素をセンタリングします。
// This jQuery centerInClient plug-in
// centers content in the window
$.fn.centerInClient = function(options) {
var opt = {
container: window,
completed: null
};
$.extend(opt, options);
return this.each(function(i) {
var el = $(this);
var jWin = $(opt.container);
var isWin = opt.container == window;
// have to make absolute
el.css("position", "absolute");
// height is off a bit so fudge it
var hFudge = 2.2;
var x = (isWin ? jWin.width() :
Win.outerWidth()) / 2 - el.outerWidth() / 2;
var y = (isWin ? jWin.height() :
jWin.outerHeight()) / hFudge -
el.outerHeight() / 2;
el.css({ left: x + jWin.scrollLeft(),
top: y + jWin.scrollTop() });
var zi = el.css("zIndex");
if (!zi || zi == "auto")
el.css("zIndex", 1);
// if specified make callback and pass element
if (opt.completed)
opt.completed(this);
});
}
このプラグインには一般的なパターンが2つ含まれています。第一に、オブジェクトマップ(すなわち、{container: "#divContainer"})として渡すことができる一群のオプションパラメータが含まれています。optがプライベート変数として定義され、optionパラメータオブジェクトで拡張されていることに注意してください。$.extend()は、オブジェクトを別のオブジェクトの内容で拡張する素晴らしいユーティリティ関数です。これによってパラメータ処理が簡単になります。なぜなら、必要なパラメータだけを渡せばよいからです。大部分のプラグインはこのやり方でオプションパラメータを受け取るので、独自のプラグインでオプションを実装するのがよいでしょう。
もう1つの一般的パターンは、jQueryマッチセットが確実に返されるようにするthis.each( function() {...});を返すことです。.each関数はマッチしたDOM要素を個々に反復処理するので、それらを一度に1つずつ操作することが可能になります。.each()関数ハンドラの内部において、thisポインタは常に反復処理されたDOM要素です。$(this)を使用すると、その要素についてjQueryのインスタンスを取得できます。通常、これはその要素を操作したいものです。
プラグインを作成するのはとても簡単なので、私は自分用と共用として、かなりの数のプラグインを自作してしまいました。単純なプラグインモデルというのがミソで、これによってjQueryがコンパクトに保たれています。つまり、jQueryには一群のコア機能だけが含まれており、しかもコアライブラリの機能をすべて拡張できるようになっているわけです。
まとめ
まるでツールの売り込み記事じゃないかと思われるかもしれませんが、実際、私は少し前にたまたまこのライブラリに巡り会って、たちまち夢中になってしまったのです。私は自分が使っているツールを非常に批判的に見る傾向がありますが、jQueryに関してはまだ重大な不満を感じていません。このライブラリは、私にとって文句なく動作しますし、期待どおりに動作します。
とはいえ、jQueryライブラリは「完璧なツール」ではないので、起こり得るJavaScriptとDOMの問題を何でも解決してくれるわけではありません。それでも、1年以上使っていて、まだ特に大きな問題には遭遇していません。しかし、非DOM関連機能に役立つ若干のヘルパー関数が必要かもしれません。例えば、私は日付と数値の書式化やウィンドウ関係のサポートやその他のさまざまな機能を使用するために、依然として自分の古いJavaScriptライブラリを使っています。これはまだしばらく手放せそうにありません。しかしその気になれば、私の古いライブラリの多くの部分は破棄できるでしょう。その部分をjQueryで置き換えることが可能ですし、しかも多くの場合、jQueryの方が私のコードよりもずっと洗練されているはずです。
正直に言えば、私はバランスをとるために何とかjQueryの欠点を見つけようとしています。というのも、マイナス面に触れるべきだと編集者から言われたからです。努力はしたのですが、どうやら欠点については読者の皆さんに自分で探していただくしかないようです。Webをざっと検索してみた限りでは、私に似た意見の人が多いようで、jQueryを否定的に見ているコンテンツはあまりありません。けれども、実際に試してみて自分で判断することをお勧めします。
次回の予告:jQuery、AJAX、ASP.NETサーバーの統合
本稿ではクライアントサイドにおけるDOM操作とJavaScriptの拡張に関してjQueryのコア機能を取り上げましたが、AJAXおよびASP.NETとのサーバーサイド統合については説明しませんでした。これらのトピックについては次回の記事で論じることにします。次回の記事では、jQueryのAJAX機能と、ASP.NETをバックエンドとして使用してAJAX呼び出しを受け取るための種々の方法(単純なページコールバック、REST呼び出し、WCF)を説明します。また、サーバーサイドコンポーネントと組み合わせてASP.NETのコントロールをjQueryやjQueryのプラグインと統合する方法や、ASP.NETアプリケーションでjQueryのスクリプトを管理する一般的な方法についても説明します。
それまではjQueryのことを各自で調べてみてください。失望することはないはずです。
jQueryにはサーバと対話するためのAJAX関数が数多く含まれています。例えば、低レベルの$.ajax()関数には、サーバにAJAX要求を送るための多数のオプションや、一般的なシナリオを容易にする数々の単純なバリエーションが用意されています。.load()は選択した要素にHTMLを直接ロードします。$.post()と$.get()は、POST要求またはGET要求でサーバからデータを取得します。$.json()はJSON結果を返し、評価します。
これらの関数を使用すると、ASP.NETサーバコードを呼び出すことによって、ページ、ハンドラ、ASMXサービス、さらにはWCF HTTPフルサービスとも簡単に対話できます。次回の記事をお楽しみに。
参考資料
リソース
クイックリファレンスシート
書籍
- 『jQuery in Action』
- 『jQuery Reference Guide』
- 『Learning jQuery』
