jQueryプラグイン作成法のまとめ
2015/11/13
私はどちらかというとPrototype.jsライブラリをよく使ってきたのですが、最近はjQuery寄りになっていて、プラグインをいくつか作る機会が出てきました。今回は自分が参考にしたサイトなどを頼りにjQueryプラグイン作成方法をまとめてみたいと思います。
参考サイト: jQuery を扱う: 第 3 回 中級レベルの jQuery: 独自のプラグインを作成する
内容はややデベロッパー向けですが、以下のWeb技術を扱った一連のドキュメント群も非常にためになります。
技術文書一覧
プラグイン作成のマナー
別に強制力があるわけではないですが、jQueryサイドで最低限守ってほしいという規則を載せておきます。
1、ファイル名はjquery.「あなたのプラグイン名」.jsとする。
例: jquery.clickablecanvas.js
2、メソッドはjQuery.fnオブジェクトにアタッチし、関数はjQueryオブジェクトにアタッチすること。プラグインのメソッドと関数の違いは、メソッドが$(‘#element_id’).myMethod()のようにjQueryセレクターを受け取る形式で呼び出すのに対し、関数では$.myFunction()のようにjQueryオブジェクトに直接ドットシンタックスで結ぶ形式で呼び出す点です。
3、thisキーワードはすべてjQueryオブジェクトを参照すること。ただし、jQuery.fnにアタッチしたメソッドでは、自動的にコード内のthisキーワードがjQueryオブジェクトを参照します。
4、jQueryのメソッドチェーンを断ち切らないために、すべてのメソッドはjQueryオブジェクトを返す(returnする)こと。さらに一致した要素に対してくり変えし処理を行うときはthis.each()のループを使う。
5、コード内ではショートカットの「$」ではなく、必ず「jQuery」を使用すること。自分のプラグインでこれをやっていないので偉そうにいえないですが、「$」を使用する他のライブラリ(たとえばPrototype.js)との競合を防ぐのに重要な点です。jQueryにはnoConflictメソッドというのがあって、これを呼び出すことで「$」の役割をjQuery以外のライブラリに引き渡すことができます。しかし、「$」がjQueryプラグインのコード内で使われていると、noConflictメソッドが機能しなくなってしまうわけです。複数のプラグインの使用を前提とする場合は必須になるでしょう。
プラグインの構成
実際のプラグインのコードをのぞいてみると大抵、( function(jQuery) { …… } )(jQuery)のように、プラグインコード全体が無名関数のなかに記述され、さらにプラグインが読みこまれたらすぐに実行するように、その関数にjQueryオブジェクトを引数に渡す形になっています。
(function(jQuery) { //ここにプラグインのコードを記述 ........ ........ ........ })(jQuery);
(追記 2015/11)コメントにご指摘がありましたが、即時実行の関数の仮引数は$としても外部を汚染する可能性がないので、記述の簡略化のため、仮引数を$とする方を推奨します。
(function($) { //この仮引数を$に変更しても問題ありません //ここにプラグインのコードを記述 $.fn........ ........ ........ })(jQuery); //ここはjQueryのままで……
このような記述方法にする利点は、プラグインのコード内でグローバル変数を一切使わなくて済むということです。プラグインで定義される変数をこの無名関数内で宣言すれば、すべてローカル変数になるので、グローバル名前空間を汚さずに済むわけです。
次にプラグインコード内で使用するメソッドは、任意で外部/内部メソッドに分けることができます。たとえばプラグインを呼び出すメソッドは、当然外部からアクセスできなければならないので外部メソッドになります。一方で内部の作業などで使用されるだけであれば、外部からアクセスできない内部メソッドとして登録します。前回書いたようなクロージャの特性を利用して、外部/内部メソッドの作成は次のようにします。
(function(jQuery) { //プラグイン内部で使用する変数をスコープの最上層で宣言しておけば、コード内のどこでも使用できる var hensu1 = 1000, hensu2 = 'hoge', hensu3; //外部からアクセス可能なメソッドはjQuery.fnにアタッチする。最後のセミコロンは必要 jQuery.fn.publicMethod = function() { ........ ........ ........ }; //内部的に使用されるメソッドは、無名関数内で関数定義する。関数定義なので最後のセミコロンは不要 function privateMethod() { ........ ........ ........ } })(jQuery);
メソッドのthisと戻り値
jQuery.fnにアタッチしたプラグインメソッドでは、thisキーワードがjQueryオブジェクトに変換された要素になるはずです。このメソッドの連鎖が切れないように、メソッドの戻り値はthisキーワードか、あるいはthis.each()による処理の結果を指定します。通常は後者のthis.each()を返すよう推奨されています。
(function(jQuery) { //myPlugin1メソッドとmyPlugin2メソッドでしていることは同じ。ただし、myPlugin2メソッドの方法が推奨されている。 jQuery.fn.myPlugin1 = function() { this.css({ color: '#999' }); return this; }; jQuery.fn.myPlugin2 = function() { return this.each(function() { jQuery(this).css({ color: '#999' }); }); }; })(jQuery);
オプションを受け取る
多くのプラグインは最初に呼び出すとき、オプションを設定できるように作られています。複数のオプションがあるときは、大抵オブジェクト形式で受け取ります。ここで使用するのが、オブジェクトを拡張するメソッドjQuery.extendです。
(function(jQuery) { //このようにデフォルトのオプションを上書きするように設定する jQuery.fn.startPlugin = function(options) { var options = jQuery.extend({ opt1: 100, opt2: true, ........ ........ }, options); //ユーザーのオプション上書きがなければ次のようになる alert( options.opt1 ); //100 alert( options.opt2 ); //true ........ ........ return this.each(function() { ........ ........ ........ }); }; })(jQuery);
ユーザー側がオプションを指定するには、プラグインを呼び出したとき次のようにメソッドの引数にオブジェクトを渡します。ユーザーのスクリプトはページのロードが終了した後に実行される方が都合がいい場合が多いので、jQueryオブジェクトに無名関数を渡す形式($(function() { …… }))にします。なお、readyメソッドで$(document).ready(function() { …… })のようにしても同様の働きをします。
$(function() { //$(function() { ....... })と記述すると、ページのロードが終了した後にjQueryオブジェクトに渡したコールバック関数が実行される jQuery('#element_id').startPlugin({ opt1: 500, opt2: false }); });
とりあえず以上……。作成に必要な最低限のまとめになりました。