次のような単純なものから始めたいと思うかもしれません:
function MaterObject(selector) {
this.selector = selector;
this.elements = document.querySelectorAll(selector);
}
次に、MasterObject.prototype を使用して機能を追加します。
MasterObject.prototype = {
getLength: function() {
return this.elements.length;
},
refresh: function() {
this.elements = document.querySelectorAll(this.selector);
return this;
},
addMore: function(selector) {
this.selector = this.selector + ',' + selector;
this.refresh();
return this;
}
}
等々。それを開始するには:
function $(selector) {
return new MasterObject(selector);
}
上記には機能テストが欠けているため、脆弱です。
jQuery の多くはオーバーロードされているため、与えられたものをテストしてから、結果を処理することを決定する必要があることに注意してください (「isArray」の有名なケースが思い浮かびます)。メソッドを呼び出すと、セレクターによって選択されたすべての要素、または最初の要素だけに対して何かが行われる場合があります。メソッドに文字列、オブジェクト、または何も渡さないと、メソッドの動作が完全に変わる場合があります。
this
メソッドをチェーンできるように、関数は戻ることができることに注意してください。ただし、(ライブラリの設計者とユーザーの両方にとって) 問題は、チェーン可能にする必要があるものとそうでないものを特定することです。たとえば、
var $x = $('div');
// addMore is chainable, getLength isn't
$x.addMore('p').getLength();
編集
「jQuery」オブジェクトを配列にしたい場合は、継承するすべてのメソッドを Array.prototype に追加する必要がありますが、これはあまり良い考えではありません。他に方法はありません。配列オブジェクトを作成して独自のプロトタイプ オブジェクトをその[[Prototype]]
チェーンに挿入することはできません。配列インスタンスは Array.prototype から直接継承されます。
できる最善の方法は、要素 NodeList を配列に変換し (OP で行うように)、その上で配列のようなメソッドを呼び出すことです (結果として、セレクターが要素配列の内容を表していない可能性があることに注意してください)。
function MasterObject(selector) {
this.selector = selector;
this.elements = [];
}
MasterObject.prototype = {
...
refresh: function() {
this.elements = [];
var els = document.querySelectorAll(this.selector);
for (var i=0, iLen=els.length; i<iLen; i++) {
this.elements[i] = els[i];
}
return this;
},
pop: function() {
return this.elements.pop();
},
おそらく、そのような変更は DOM に反映される必要があります (この場合、qSA を介して再度選択する必要なく、セレクターがコンテンツと同期している必要があります)。
popElement: function() {
var el = this.elements.pop();
el.parentNode.removeChild(el);
return el;
},
...
};
function $(selector) {
var newObj = new MasterObject(selector);
newObj.refresh();
return newObj;
}