jQuery 1.5 beta1 のリリースノートを見ていたら面白そうな機能があったので紹介。
1.5正式版では jQuery.sub という名称に変更になったので、本文およびサンプルコードを修正しました。
jQuery.sub() でjQueryのサブクラスを作ることができる
var MyjQuery = jQuery.sub();
作成したサブクラスには独自のメソッドを定義することができる。定義の仕方、使い方は通常のjQueryと全く同じ。
MyjQuery.fn.writeHello = function(){ this.text('Hello World'); }; MyjQuery('p').writeHello();
通常のjQueryメソッドはサブクラスでもそのまま使える。サブクラスを作った後に追加したメソッドも使えるので、プラグインによる拡張と組み合わせても大丈夫。
MyjQuery('div').css('border', '1px red solid').writeHello(); //元のjQueryを拡張 jQuery.fn.pluginMethod = function(){ alert('OK'); }; //OK MyjQuery('.klass').pluginMethod();
逆にサブクラスで追加したメソッドは元のjQueryからは見えないので、プロジェクトやプラグインに固有なメソッドを定義したり、元のjQueryにあるメソッドを上書きしたりといったことが安全にできる。
// text メソッドを上書きする MyjQuery.fn.text = function(val) { var orig = jQuery.fn.text; if(typeof val === "string") { return orig.call(this, "!!"+ val +"!!"); } else { return orig.apply(this, arguments); } }; // 上書きされたtextを呼び出す MyjQuery('#ex').text("foo"); // 引数を与えなければ元のメソッドが呼ばれる MyjQuery('#ex').text(); //!!foo!! // もちろん元のメソッドには影響ない jQuery('#ex').text('foo'); //foo
さらに応用として、プラグインで拡張メソッドを提供する場合の名前空間としても使えるかもしれない。例えば私が前に作った動的にSELECTを構築するためのjQueryプラグインは、グローバルなメソッド空間に2つのメソッドを追加してしまうのであまりマナーが良くない。
$('select').addOption(...); $('select').clearOptions(...); //本当は次のようにしたいが、動作しない $('select').optionBuilder.addOption(...); $('select').optionBuilder.clearOptions(...); //次のような実装が推奨されている $('select').optionBuilder('addOption', ...); $('select').optionBuilder('clearOptions', ...);
1.5のサブクラス機能を使えば、次のように隔離されたサブクラスでのみ使用可能なメソッドとして提供することができる。
//サブクラスを使えば直接呼び出せる var optionBuilder = jQuery.optionBuilder(); optionBuilder('select').addOption(...) optionBuilder('select').clearOptions(...); //関数の中に隔離する方法も jQuery.optionBuilder(function($){ $('select').addOption(...); $('select').clearOptions(...); });
実装は次のような感じになるだろう。
/* * jQuery.optionBuilder.fn[method](...); * を * jQuery.fn.optionBuilder(method, ...); * にマップする */ jQuery.optionBuilder = (function(){ var sub = jQuery.sub(), base = jQuery.fn.optionBuilder, slice = Array.prototype.slice, methods = ['addOption', 'clearOptions']; $.each(methods, function(i, method){ sub.fn[method] = function(){ return base.apply(this, [method].concat(slice.call(arguments))); }; }); return function(fn){ if(typeof fn === 'function') { return fn(sub); } return sub; }; }());
参考:
[...] サブクラス 既に詳しく説明されているので下記を参照されよ。 jQuery 1.5の新機能: jQueryのサブクラスが作れるようになる | へびにっき [...]