3

私は自分の小さな jquery のようなライブラリを構築しようとしていますが、この連鎖パターンを作成するのに非常に苦労しています。基本的に、ドキュメントの操作を容易にする一連のメソッドを備えた 1 つのクラスがあります。これが例です

function MF(selector){
    var DO; // Stands for DocumentObject
    this.select = function(selector){
        return document.getElementById(selector);
    }
    if(typeof selector === 'string'){
        DO = this.select(selector);
    }else if(selector instanceof HTMLElement){
        DO = selector;
    }

    this.children = function children(selector){
        return DO.getElementsByClassName(selector);
    }
    return {
        MF: ???
    }
}(null);

私の反省は間違っているかもしれませんが、ドキュメント オブジェクト ( html 要素) に追加のメソッドを追加するには、HTMLElement プロトタイプを拡張するか、クラスと共に要素を渡す必要があることがわかりました。私は2番目のオプションを選択しました。クラスで何を返す必要があるのか​​ わからないので、連鎖を続けることができます。この例のために、私が単に目指しているのは、次のコード行を記述できるようにすることです。

MF('someDiv').children('someClass');

絶望的な試みでMF、デフォルトではインスタンスを持たないはずの新しいインスタンスを返そうとしましたが、無限ループに陥りました。そこに何を返せばいいのかわからない。どんな助けでも大歓迎です!

4

4 に答える 4

2

return this;コンストラクタのメソッドへのアクセスを許可します。メソッドが別の値を返す必要がない場合は、コンストラクターの一番下とそれに属するすべてのメソッド内の一番下でそれを行います。

function MF(selector){
  var doc = document;
  this.select = function(selector){
    return doc.getElementById(selector);
  }
  // there are problems with some of your code
  this.someMethod = function(){
    /* do stuff - If you want to access an Element then
      var thisIsNowGlobal = this.select('someId');
      thisIsNowGlobal.innerHTML = 'someText';
      Note, the keyword this is global not var
      If you wrote this.select('someId').innerHTML the property would not exist

      When a property of an Object is assigned to a variable or argument
      the this value changes to the global context.
   */
    return this;
  }
  return this;
}
于 2013-11-02T23:19:26.987 に答える
1

従来、jQuery でチェーンを有効にする方法は、戻り値の型ごとにラッパー オブジェクトを作成することでした。たとえば、あなたの場合、独自のラッパーを作成するのにお金がかかりますHTMLElement

function HTMLElementWrapper(element) {
    if (element instanceof HTMLElementWrapper) return element;
    this.element = element;
}

これで、次のように関数をHTMLElementWrapperリファクタリングできます。MF

function MF(selector) {
    return new HTMLElementWrapper(typeof selector === "string" ?
        document.getElementById(selector) : selector);
}

このMF関数は、と のHTMLElementWrapper2 つのメソッドを持つオブジェクトを返すようにselectなりましたchildren

HTMLElementWrapper.prototype.select = function (selector) {
    return new HTMLElementWrapper(this.element.getElementById(selector));
};

HTMLElementWrapper.prototype.children = function (selector) {
    return new NodeListWrapper(this.element.getElementsByClassName(selector));
};

もちろん、関数を機能させるには、コンストラクターchildrenを作成する必要があります。NodeListWrapper

function NodeListWrapper(list) {
    if (list instanceof NodeListWrapper) return list;
    this.list = list;
}

これで、次のようにメソッドをチェーンできます。

MF("someDiv").select("something").children("someClass");

.children("someClass")これらのメソッドを に追加する必要がある後でメソッドをチェーンするにはNodeListWrapper.prototype

于 2013-11-02T23:59:06.813 に答える