jQuery の基礎からプラグインの作成までを解説
オリジナル: http://jquery.bassistance.de/jquery-getting-started.html
作者: Jörn Zaefferer
このスタートガイドでは、jQuery ライブラリの概要を説明します。対象読者は、JavaScript と DOM (Document Object Model) に関する基礎知識を持っているユーザーです。ごく初歩的なことから始めて、必要な場合には細かな部分まで立ち入って説明します。簡単な Hello world サンプルのほか、セレクタとイベントの基礎、AJAX、FX、およびプラグインの使用と作成について取り上げます。
このスタートガイドでは、クリックするだけで表示されるような簡単なサンプルは用意していません。コードをコピーして実行するようにしているのは、ユーザーが自分で試してみる方が望ましいと考えるからです。実際にサンプルをコピーして、どんなふうに動作するか確認し、自分でいろいろと手をいれてみてください。
目次 |
このスタートガイドで説明する手順を実行するには、jQuery ライブラリが必要です。jQuery ライブラリは、ダウンロードページから入手できます。サンプルの実行に必要なマークアップと CSS の一部は、jQuery スターターキットに含まれています。スターターキットをダウンロードして展開したら、同じディレクトリに jquery.js を置いてください。次に、starterkit.html と custom.js を好みのエディタで開き、ブラウザで starterkit.html を開きます。
これで、おなじみの "Hello world" サンプルを実行できるようになりました。
関連リンク:
まず、次のような空の HTML ページを用意します。
<html> <head> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> // ここに JavaScript コードを追加 </script> </head> <body> <!-- ここに HTML コンテンツを追加 --> </body> </html>
このページは、jquery.js ライブラリをロードするだけのページです (jquery.js の URL は、jquery が置かれている場所を指すようにしてください。上の例では、サンプルファイルと jquery.js は同じディレクトリに置かれていることを前提にしています)。2 つのコメントは、コードを追加する場所を示します。
jQuery を使ったほとんどの処理では、DOM を読み取ったり操作したりするので、イベントの追加などは、DOM の準備完了後すぐに開始する必要があります。
それには、ドキュメントの ready イベントを登録します。
$(document).ready(function() {
// DOM の準備完了時に行う処理を記述
});
この関数に警告を記述してもあまり意味はありません。なぜなら、DOM が読み込まれなくても警告は実行できるからです。そこで、もう少し複雑な処理を行ってみましょう。リンクをクリックしたときに警告が表示されるようにします。
<body> の部分に次のコードを追加します。
<a href="">Link</a>
そして、$(document).ready ハンドラを更新します。
$(document).ready(function() {
$("a").click(function() {
alert("Hello world!");
});
});
これで、リンクをクリックすると、警告が表示されるようになります。このスクリプトをコピーして custom.js ファイルに貼り付けてください。次に、ブラウザで starterkit.html を開き、任意のリンクをクリックします。どのリンクをクリックしても、ポップアップウィンドウが開いて "Hello world!" というメッセージが表示されるはずです。
順を追って解説しましょう。$("a") は jQuery のセレクタで、上の例ではすべての a 要素を選択します。このうち $ そのものは jQuery「クラス」のエイリアスです。したがって、$() は新しい jQuery オブジェクトを作成します。次に呼ばれている click() 関数は、jQuery オブジェクトのメソッドです。このメソッドは、すべての選択された要素 (上の例ではアンカー要素のみ) にクリックイベントをバインドし、クリックイベントが発生したときに、指定された関数を実行します。
実際の動作は、次のコードに似ています。
<a href="" onclick="alert('Hello world')">Link</a>
違いは明白です。jQuery を使えば、各要素ごとに onclick を記述する必要はありません。また、CSS を使って構造と表現を分離するのとまったく同様に、構造 (HTML) と動作 (JS) をはっきりと分離することができます。
この点を念頭に置いて、セレクタとイベントについてもう少し詳しく見てみましょう。
関連リンク:
jQuery では、要素を選択するためのアプローチを 2 つ用意しています。1 つは、CSS セレクタと XPath セレクタを組み合わせて、これを文字列として jQuery のコンストラクタに渡す方法です (例: $("div > ul a"))。もう 1 つは、jQuery オブジェクトのいくつかのメソッドを使う方法です。この 2 つの方法は組み合わせて使うことができます。
実際にこうしたセレクタをいくつか試すために、スターターキットの中の最初の番号付きリストを選択して修正してみましょう。
最初に、目的のリストそれ自体を選択します。リストの ID は "orderedlist" です。従来の JavaScript なら、document.getElementById("orderedlist") を使って、リストを選択することができます。jQuery では、次のようにします。
$(document).ready(function() {
$("#orderedlist").addClass("red");
});
スターターキットには、赤い背景を追加するクラス "red" を持つスタイルシートが含まれています。したがって、ブラウザでスターターキットのページをリロードすると、最初の番号付きリストの背景が赤になるはずです。2 番目のリストは元のままで変わりません。
では、最初のリストの子要素にいくつかクラスを追加してみましょう。
$(document).ready(function() {
$("#orderedlist > li").addClass("blue");
});
こうすると、ID に orderedlist を持つ要素のすべての子 li を選択し、クラス "blue" を追加します。
今度はもう少し複雑な処理をしてみましょう。ユーザーが li 要素をマウスでポイントしたときにクラスを追加して削除します。ただし、対象となる li 要素は、リストの中の最後の要素だけに限定します。
$(document).ready(function() {
$("#orderedlist li:last").hover(function() {
$(this).addClass("green");
},function(){
$(this).removeClass("green");
});
});
CSS と XPath の構文に似たセレクタは、ほかにも数多くあります。もっと多くの例や、利用可能なすべての式のリストについては、こちらを参照してください。
onclick、onchange、onsubmit など、利用可能なすべての onxxx イベントについては、対応するイベントが jQuery にも用意されています。また、特定のタスクに便利なメソッドとして、ready や hover などのその他のイベントも用意されています。
用意されているすべてのイベントのリストについては、jQuery イベントのドキュメントを参照してください。
セレクタとイベントを使うと、さまざまなことを実行できますが、jQuery ではさらに次のようなこともできます。
$(document).ready(function() {
$("#orderedlist").find("li").each(function(i) {
$(this).append( " BAM! " + i );
});
});
find() を使うと、すでに選択された要素の子孫をさらに絞り込むことができます。したがって、上の $("#orderedlist").find("li") は、$("#orderedlist li") とほぼ同じです。
each() は、各要素に対して繰り返し処理を行います。addClass() をはじめとするほとんどのメソッドは、それ自体の中で each() を使っています。
上の例では、append() を使って各要素の末尾にテキストを追加します。
このほかによく行う作業として、jQuery の操作対象外の DOM 要素に対してメソッドを呼び出す作業があります。たとえば、Ajax 経由で問題なく送信できたフォームをリセットする場合などです。
$(document).ready(function() {
// 単一のフォームをリセットする場合
$("#reset").click(function() {
$("form")[0].reset();
});
});
上のコードは、最初のフォームを選択し、選択したフォームに対して reset() を呼び出します。フォームが複数ある場合は、次のようにします。
$(document).ready(function() {
// 複数のフォームをまとめてリセットする場合
$("#reset").click(function() {
$("form").each(function() {
this.reset();
});
});
});
このコードは、ドキュメント内のすべてのフォームを選択し、各フォームに対して繰り返し reset() を呼び出します。.each() 関数内部では this が実際の要素を表すことに注意してください。
また、reset() 関数はフォーム要素に属していて、jQuery オブジェクトではないので、$("form").reset() を呼び出しても、ページ上のすべてのフォームをリセットすることはできない点に注意してください。
よく行うもう 1 つの作業に、同種または同一の一連の要素の中から、一部の要素だけを選択する作業があります。こうした作業のために、jQuery では filter() と not() を用意しています。filter() は、選択の対象をフィルタ式に一致する要素に限定するのに対し、not() はその逆の操作を行い、式に一致するすべての要素を選択の対象から除外します。たとえば、番号なしリストから、子 ul 要素を持たないすべての li 要素を選択するには、次のようにします。
$(document).ready(function() {
$("li").not(":has(ul)").css("border", "1px solid black");
});
このコードは、子要素に ul を持つすべての li 要素を選択し、これらの要素を選択対象から除外します。したがって、子要素に ul を持つ li 要素を除くすべての li 要素は、境界線を持つことになります。
[式] という構文は XPath から取られたもので、これを使うと属性によるフィルタリングが可能になります。たとえば、name 属性を持つすべてのアンカーを選択するには、次のようにします。
$(document).ready(function() {
$("a[name]").css("background", "#eee" );
});
このコードは、name 属性を持つすべてのアンカー要素に背景色を追加します。
一般的には、name 属性でアンカーを選択する場合よりも、"href" 属性でアンカーを選択する必要がある場合の方が多いでしょう。ただ、返される "href" の値はブラウザによってかなり異なるので、この操作は必ずしも簡単ではありません (注:この問題は 1.1.1 以降の最近の jQuery では解決済みです)。値の一部にマッチさせるには、等号 ("=") ではなく、右辺を含む値を選択する "*=" を使用して、次のようにします。
$(document).ready(function() {
$("a[href*=/content/gallery]").click(function() {
// /content/gallery のいずれかの場所を指すすべてのリンクを対象とする処理を記述
});
});
これまでに取り上げたセレクタはいずれも現在の選択対象の子を選択したり、現在の選択対象を絞り込んだりするものでした。しかし、前の要素や次の要素など、兄弟要素の選択が必要になる場合もあります。たとえば、FAQ ページで最初は回答をすべて非表示にしておいて、質問がクリックされたら回答が表示されるようにする場合などです。これを jQuery で記述すると、次のようになります。
$(document).ready(function() {
$('#faq').find('dd').hide().end().find('dt').click(function() {
$(this).next().slideToggle();
});
});
上の例では、'#faq' の選択を一度だけで済ませ、コードサイズを小さくしてパフォーマンスを上げるために、連鎖法を使っています。end() を使うと、最初の find() が取り消されるので、次の find() では、子 dd 要素ではなく #faq 要素に対して新しく検索を開始することができます。
click() メソッドに渡される関数であるクリックハンドラの内部では、$(this).next() を使って、現在の dt 要素を起点に次の兄弟要素を探しています。これで、クリックされた質問の回答をすばやく選択することができます。
兄弟要素のほかに、親要素 (XPath の祖先に相当) を選択することもできます。たとえば、ユーザーがリンクをポイントしたときに、そのリンクの親にあたる段落を強調表示するには、次のようにします。
$(document).ready(function(){
$("a").hover(function(){
$(this).parents("p").addClass("highlight");
},function(){
$(this).parents("p").removeClass("highlight");
});
});
上の例では、マウスでポイントされたすべての要素を対象に、親の段落を検索してクラス "highlight" を追加し、ついで削除しています。
先へ進む前に、少し後戻りして jQuery の優れた点をみておきましょう。jQuery ではコードを短くできるので、可読性と保守性を高めることができます。次に示すのは、$(document).ready(callback) の省略記法です。
$(function() {
// DOM の準備完了時に実行するコードを記述
});
すでに取り上げた Hello world! サンプルにこの記法を適用すれば、次のように記述できます。
$(function() {
$("a").click(function() {
alert("Hello world!");
});
});
では、これまでに学んだ基礎知識をふまえて、jQuery のその他の側面についてもみていきましょう。最初に AJAX を取り上げます。
関連リンク:
ここでは小さな Ajax アプリケーションを作成し、youtube.com で行われているように、ユーザーが投票によってランク付けできるようにしてみましょう。
このアプリケーションではいくらかサーバーコードが必要で、サンプルの php ファイルでは、"rating" パラメータを読み取って、投票数とランクの平均値を返します。サーバーサイドコードの具体的な内容については、rate.php を参照してください。
サンプルを Ajax を使わずに動作させることは可能ですが、ここでは Ajax を使って動作させるため、必要なマークアップを jQuery で生成し、"rating" を ID に持つコンテナ div に追記します。
$(document).ready(function() {
// マークアップを生成
$("#rating").append("Please rate: ");
for ( var i = 1; i <= 5; i++ )
$("#rating").append("<a href='#'>" + i + "</a> ");
// マークアップをコンテナに追加し、クリックハンドラをアンカーに適用
$("#rating a").click(function(e){
// リンクをクリックしたときの通常の動作をストップ
e.preventDefault();
// リクエストを送信
$.post("rate.php", {rating: $(this).html()}, function(xml) {
// 結果を整形して出力
$("#rating").html(
"Thanks for rating, current average: " +
$("average", xml).text() +
", number of votes: " +
$("count", xml).text()
);
});
});
});
上のコードは 5 つのアンカー要素を生成し、これを "rating" を ID に持つコンテナ要素に追記します。その後、コンテナ内の各アンカーに対してクリックハンドラを追加します。アンカーがクリックされると、アンカーの内容をパラメータとして rate.php に POST リクエストが送信されます。結果は XML として返されてコンテナに追加され、アンカーは結果で置き換えられます。
PHP がインストールされた Web サーバーが手元にない場合は、オンラインサンプルで動作を確認できます。また、JavaScript なしでも動作するたいへん優れた投票システムの例が softonic.de にあるので[訳注:リンク切れ]、"Kurz bewerten!" をクリックしてみてください。
jQuery の Ajax メソッドの詳細については、Ajax ドキュメント、または Visual jQuery の Ajax の項を参照してください。
これは Ajax でコンテンツを読み込むときによく遭遇する問題ですが、ドキュメントにイベントハンドラを追加する場合で、読み込まれたコンテンツにもこれらのハンドラを適用する必要があるときは、コンテンツが読み込まれた後にこれらのイベントハンドラを適用する必要があります。具体的には、コードが重複するのを避けるために、次の例のようにハンドラを関数にします。
function addClickHandlers() {
$("a.remote", this).click(function() {
$("#target").load(this.href, addClickHandlers);
});
}
$(document).ready(addClickHandlers);
こうすると、addClickHandlers は DOM の準備完了後に一度だけ呼び出され、その後は、クラス remote のリンクをユーザーがクリックし、コンテンツが読み込まれるたびに呼び出されるようになります。
ここで $("a.remote", this) クエリーに注目してください。this はコンテキストとして渡されます。ドキュメントの ready イベントでは、this はドキュメントを指し、したがってドキュメント全体でクラス remote のアンカーを探します。一方、addClickHandlers が load() のコールバックとして使われるときには、this は異なる要素を指します。上の例の場合、具体的には "target" を ID に持つ要素です。このため、クリックイベントが同じリンクに繰り返し何度も適用されて、最終的にクラッシュを引き起こすような事態を回避することができます。
コールバックに関してもう 1 つよく問題になるのは、パラメータの処理です。コールバックを指定するときに、追加でパラメータを渡したいことがあります。これを実現するための最も簡単な方法は、次のようにコールバックを関数内にラップすることです。
// 何らかのデータを取得
var foobar = ...;
// パラメータに data を必要とするハンドラを指定
function handler(data) {
//...
}
// クリックハンドラを追加し、foobar を渡す
$('a').click(function(){
handler(foobar);
});
// 元のハンドラのコンテキストが必要な場合は、次のようにして apply を使用
$('a').click(function(){
handler.apply(this, [foobar]);
});
このような簡単な Ajax によって、"Web 2.0" のかなりの部分をカバーすることができます。さて、Ajax の基本を押さえたので、今度は簡単な効果 (エフェクト) とアニメーションをページに追加してみましょう。
関連リンク:
jQuery では show() と hide() を使うことで簡単なアニメーションが可能になります。
$(document).ready(function(){
$("a").toggle(function(){
$(".stuff").hide('slow');
},function(){
$(".stuff").show('fast');
});
});
animate() を使えば、フェードするスライドなど、アニメーションを任意に組み合わせることができます。
$(document).ready(function(){
$("a").toggle(function(){
$(".stuff").animate({ height: 'hide', opacity: 'hide' }, 'slow');
},function(){
$(".stuff").animate({ height: 'show', opacity: 'show' }, 'slow');
});
});
Interface プラグインコレクションを使うと、もっと多彩なエフェクトを実現できます。このサイトにデモとドキュメントもあるので参照してください。Interface は jQuery プラグインの中で最も知名度がありますが、このほかにも多数のプラグインがあります。次のセクションでは、tablesorter プラグインを使う例を取り上げます。
関連リンク:
tablesorter プラグインを使うと、クライアント側でテーブルを並べ替えることができます。そのためには、jQuery をインクルードし、次に tablesorter プラグインをインクルードして、どのテーブルを並べ替えの対象にするのかを tablesorter プラグインに指示します。
以下のサンプルを実際に試してみるには、tablesorter プラグインをダウンロードし、starterkit.html に次の行を (jquery をインクルードしている行の下に) 追加する必要があります。
<script src="jquery.tablesorter.js"></script>
プラグインをインクルードしたら、次の要領で呼び出すことができます。
$(document).ready(function(){
$("#large").tablesorter();
});
テーブルの見出しをクリックすると、最初は昇順に並べ替えられ、次にクリックすると降順に並べ替えられます。
次のようにオプションを指定することで、テーブルの一部の行を強調表示することもできます。
$(document).ready(function() {
$("#large").tablesorter({
// ストライプ模様にする
widgets: ['zebra']
});
});
利用できるオプションについての詳しい説明とサンプルは tablesorter ホームページにあります。
ほとんどのプラグインも同じようにして使用できます。すなわち、まずプラグインファイルをインクルードし、目的の要素に対してプラグインのメソッドを呼び出し、必要ならプラグインをカスタマイズするためのオプション設定を渡します。
利用可能なプラグインの最新のリストは、jQuery プラグインのサイトにあります。
jQuery をひんぱんに使う場合には、自分が使うコードをプラグインとしてパッケージ化しておくと、自分で使ったり社内で使ってもらったり、コミュニティに公開してたくさんの人に使ってもらうことができて便利です。次のセクションでは、プラグインの作成方法について簡単に説明します。
関連リンク:
jQuery で使う独自のプラグインは簡単に作成できます。以下に示すいくつかの規則を守れば、作成したプラグインはほかのユーザーからも簡単に使用できるようになります。
プラグインの命名
プラグインに名前を付けます。ここでは、例として "foobar" という名前を付けることにしましょう。名前が決まったら、jquery.[yourpluginname].js という名前のファイルを作成します。プラグインの名前が "foobar" なら jquery.foobar.js です。
独自のメソッドの追加
jQuery オブジェクトを拡張してプラグインのメソッドを 1 つまたは複数作成します。
jQuery.fn.foobar = function() {
// 何らかの処理を記述
};
作成したメソッドは次のようにしてアクセスできます。
$(...).foobar();
デフォルト設定:
ユーザーが変更可能なデフォルト設定を用意します。たとえば、次のようにします。
jQuery.fn.foobar = function(options) {
var settings = jQuery.extend({
value: 5, name: "pete", bar: 655
}, options);
};
デフォルト設定を使う場合、次のようにしてプラグインを呼び出すことができます。
$("...").foobar();
オプションを指定する場合は、次のようにします。
$("...").foobar({ value: 123, bar: 9 });
ドキュメント
作成したプラグインを公開する場合は、いくつかのサンプルとドキュメントも用意する必要があります。公開されているプラグインはたくさんあるので、参考にするとよいでしょう。
以上で、プラグインの作成方法の基本は押さえたので、実際にプラグインを作成してみましょう。
Checkbox プラグイン
jQuery でフォームを操作しようとして多くの人が試みるのは、オプションボタンやチェックボックスをオンまたはオフにすることです。その場合、だいたいは次のようなコードに落ち着きます。
$(":checkbox").each(function() {
this.checked = true;
this.checked = false; // オフにする
this.checked = !this.checked; // オンとオフを切り替える
});
上のように、コードの中に each があるときは常に、簡単にプラグインに書き換えることができます。具体的には、次のようになります。
jQuery.fn.check = function() {
return this.each(function() {
this.checked = true;
});
};
このプラグインは、次のようにして使用できます。
$(":checkbox").check();
uncheck() や toggleCheck() に対しても、同様にプラグインを書くことができます。しかし、ここではすでに作成したプラグインを拡張して、オプションを受け付けるようにしてみましょう。
jQuery.fn.check = function(mode) {
// mode が未定義の場合は 'on' をデフォルトとして使用
var mode = mode || 'on';
return this.each(function() {
switch(mode) {
case 'on':
this.checked = true;
break;
case 'off':
this.checked = false;
break;
case 'toggle':
this.checked = !this.checked;
break;
}
});
};
オプションのデフォルトを用意しておくことで、ユーザーはオプションを省略したり、"on"、"off"、または "toggle" のいずれかを指定したりできます。
$(":checkbox").check();
$(":checkbox").check('on');
$(":checkbox").check('off');
$(":checkbox").check('toggle');
オプション設定
オプション設定が複数あるときは、上の方法では指定が少々面倒です。たとえば、最初のパラメータを省略して、2番目のパラメータだけを指定する場合、不要なパラメータに対しては null 値を渡さなければならないからです。
前のセクションで取り上げた tablesorter プラグインの使用例では、オブジェクトリテラルを使ってこの問題を回避する方法を示しました。この方法を使う場合、ユーザーはすべてのパラメータを省略することもできれば、キーと値のペアを指定したオブジェクトを渡して、必要なだけ設定を上書きすることもできます。
練習として、すでに取り上げた投票用のコードをプラグインに書き換えてみましょう。プラグインのスケルトンは、おおよそ次のようになるはずです。
jQuery.fn.rateMe = function(options) {
// $("#rating") で静的コンテナを選択する代わりに
// jQuery のコンテキストを使用
var container = this;
var settings = jQuery.extend({
url: "rate.php"
// 必要なだけデフォルトを指定
}, options);
// ... 残りのコードはここに記述 ...
// 可能な場合には "this" を返して連鎖を断ち切らないようにする
return this;
});
こうすれば、プラグインを次のようにして実行することができます。
$(...).rateMe({ url: "test.php" });
これからも JavaScript で開発する機会が多い場合は、FireBug と呼ばれる Firefox の拡張機能を利用するとよいでしょう。コンソール (警告に置き換えて使用できます) やデバッガをはじめ、毎日の JavaScript 開発に役立つ各種の便利な機能が備わっています。
解決できない問題に遭遇したり、いいアイデアが浮かんだり、jQuery に関する意見を述べたりしたい場合には、遠慮なく jQuery メーリングリストに投稿してください。
このスタートガイドに関して何かあれば、私のブログにコメントを投稿するか、直接連絡をください。
最後にひと言... すばらしいライブラリを用意してくれた John Resig に深く感謝! John にたくさんのコーヒーとその他もろもろを提供してくれた jQuery コミュニティに感謝!
Categories: JQuery Core | Selectors | Attributes | Traversing | Manipulation | Events | Effects | Ajax | Plugins | Tutorials