jQuery逆引きリファレンス
jQueryプラグインを自作するには?($.fn)
何度も利用する似たコードは、ライブラリではなくプラグインにまとめよう。プラグイン作成の基本を解説。
jQueryでアプリを開発していて、似たようなコードを何度も見かけるようになってきたら、プラグイン化することを検討すべきです。本サイトでも、jQuery UI、jQuery Mobileなどのプラグインを解説していますが、こうしたプラグインは(もちろん)自分でも作成できます。何度も利用するような機能は、無秩序に自己流の関数/クラスライブラリにしてしまうのではなく(ましてや、似たようなコードをコピペするのではなく)、プラグインとしてまとめることで、利用する際にも一貫性を維持でき、結果としてコードの見通しもよくなります。
本稿では、confirmプラグインの作成を通じて、プラグインの基本を学びます。confirmプラグインは、ボタンクリック時に確認ダイアログを表示して、[OK]ボタンが選択された場合は後続の処理を継続し、[いいえ]ボタンが選択された場合には処理をキャンセルする、ごくシンプルなプラグインです。
confirmプラグインの使い方
プラグインそのもののコードを解説する前に、イメージをつかみやすくするために、confirmプラグインを利用する側のコードを確認しておきます。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>jQuery TIPS</title>
</head>
<body>
<form>
<div>
<label for="keyword">キーワード:</label>
<input id="keyword" type="text" size="20" />
<input id="search" type="button" value="検索" />
</div>
</form>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<!--confirmプラグインをインポート-->
<script src="jquery.confirm.js"></script>
<script>
$(function() {
// confirmプラグインを適用
$('#search')
.confirm()
// クリック時の挙動を定義
.click(function() {
console.log('処理が実行されました。');
});
});
</script>
</body>
</html>
|
確認ダイアログで[OK]ボタンをクリックした場合にだけ、ログが出力される(=後続のclick
イベントが処理される)ことを確認してください。
リストの太字部分に注目してみると、$(...).メソッド(...)
というおなじみの形式でconfirmプラグインの機能を呼び出せることが確認できます。プラグインとして機能をまとめれば、コードにも一貫性が出ると述べた、これが理由です。
confirmプラグインの作成
confirmプラグインの動作を確認できたところで、プラグイン本体のコードを確認してみましょう。
(function($) {
$.fn.confirm = function() {
this.click(function(e) {
if(!confirm('処理を継続してよろしいですか?')) {
e.preventDefault();
e.stopImmediatePropagation();
}
});
return this;
};
})(jQuery);
|
短いコードですが、注目すべきポイントはさまざまです。
1「(function($) {...})(jQuery);」でくくること
プラグインを作成する際、そこで利用している変数/関数はグローバルに公開すべきではありません。プラグイン作成にかかわらず、グローバルな名前空間の汚染を最大限防ぐことは、プログラミングの基本です。
そこでプラグイン全体を、即時関数――(function($) {...})(jQuery);
でくくることで、プラグインで利用する変数/関数を全てローカルスコープに押し込めることができます。
即時関数の引数$
に対して、明示的にjQueryを渡しているのは、他のライブラリ(例えばprototype.jsなど)との競合を防ぐためです。(function($) {...})(jQuery);
とすることで、即時関数の中では$()
をjQuery()
として利用できます。
[Note]即時関数
JavaScriptでは、関数という単位でスコープが決定します。その性質を利用して、関数をスコープの枠組みとして使ってしまおうというのが、即時関数のアイデアです。(function($) { ... })
のように関数を定義しておいて、その直後で即座に実行することから、そのように呼ばれます。
即時関数の配下で定義された変数/関数は、全て関数スコープ(=ローカルスコープ)ですので、グローバルな名前空間を汚すことはありませんし、外から参照することもできません。
2「$.fn.メソッド名 = ~」でプラグインを定義
$.fn
は、jQuery
オブジェクトのprototypeオブジェクトです。プラグインというと、いかにも特殊なものに思えますが、要は、標準のjQuery
オブジェクトに対してインスタンスメソッドを拡張するということです。
これには、$.fn.メソッド名 = function() { ... };
のように表します。function() { ... }
の配下では、this
でプラグインを呼び出したときのjQuery
オブジェクトを表します。例えば、先ほどの例では、
$('#search').confirm()
としていましたので、this
=$('#search')
ということです。プラグインの中で$('#search')
のように決め打ちで対象の要素を表してしまうと、応用が利かなくなってしまいますので、対象の要素にはthis
でアクセスする、と覚えておきましょう。
なお、イベントリスナーの場合と異なり、this
はあくまで(標準の要素オブジェクトではなく)jQuery
オブジェクトです。$(this)
のようなラッピングは不要である点にも注意してください。
ここでも、this.click~
でclick
イベントリスナーを定義し、その中で確認ダイアログを表示するとともに、[キャンセル]ボタンがクリックされた場合にイベント処理をキャンセルしています。イベント処理の中断については、別稿「TIPS:イベント処理を中断するには?」も併せて参照してください。
3戻り値はjQueryオブジェクトを返す
jQueryでは、$(...).attr(...).css(...)
のように、関連するメソッドをドット演算子で順に連結して呼び出すことができます(メソッドチェーン)。メソッドチェーンは、jQueryメソッドが自分自身(jQuery
オブジェクト)を返すことを利用した記法です。
メソッドチェーンはjQueryの入門書などでも最初に語られる性質の1つで、プラグインを作成する上でも、メソッドチェーンの性質を損なわないことが求められます。つまり、プラグイン(メソッド)は特別に意味ある値を返すのでない限り*1、jQuery
オブジェクトを返すように書くのがお作法です。これには、プラグインメソッドの末尾でreturn this;
とするだけです。先ほども触れたように、プラグインメソッドの中では、this
が操作対象の要素(jQuery
オブジェクト)を表すのでした。
- *1 例えば
height()
のように、要素の高さを返すことを目的としたメソッドの場合は、例外です。
API:jQuery.fn(jQueryプロトタイプオブジェクト) カテゴリ:内部処理(Internals)
※以下では、本稿の前後を合わせて5回分(第29回~第33回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
29. JavaScriptとHTMLを明確に分離するには?(data)
jQueryのdataメソッドを使って独自データ属性の値を取得することにより、「控えめなJavaScript」を実現する方法を説明する。