2

プラグイン (Pikaday) を変更して、独自の機能を少し追加しようとしています。

プラグインはプロトタイプ システムを使用して構築されており、その中に関数を追加しました。

Pikaday.prototype = {

   //OTHER PARTS OF PLUGIN

  showYearPicker: function()
        {
            document.getElementsByClassName('pika-year-label').onclick=function(){
                console.log("asfd");
            }
        }, 

    //OTHER PARTS OF PLUGIN
}

return Pikaday;

私が理解できないのは、このメソッドを実際にトリガーする方法です。指定した要素をクリックしても機能しません。

この関数をプラグインの一部として含める方法を知っている人はいますか?

誰かが興味を持っている場合は、完全なコード(私の追加を除く)​​ がここにあります。

4

1 に答える 1

3

簡単に言えば、関数のプロトタイプにメソッドを定義するということは、この関数のすべてのインスタンスからプロトタイプ チェーンの 1 つ上のリンクになるオブジェクトにメソッドを定義したことを意味します。

その関数のすべてのインスタンスの共通の「親」または「上にあるオブジェクト」と考えることができます。

したがって、メソッドを使用するには、プラグインをインスタンス化し、関数を呼び出す必要があります。

function Pikaday() {}

Pikaday.prototype = {

  showYearPicker: function() {
    console.log('called');
  }
}

let pikaday = new Pikaday();
pikaday.showYearPicker(); // <-- call the function on the prototype

これが行うことは、定義されているかどうかを確認することですpikadayshowYearPicker定義されていないため、proto チェーンを上って、そのオブジェクトがそれを持っているかどうかを確認します。

つまり、これは基本的に JS エンジンが舞台裏で行っていることです。

let pikaday = new Pikaday();
pikaday.__proto__.showYearPicker();

ここでのprotoはデモンストレーション用であり、レガシー目的で ES6 で最近標準化されたばかりですが、この動作は JS エンジンに任せる必要があります (仕様では、この proto リンクを呼び出します[[Prototype]])。

必要に応じて、プロトタイプにアクセスする適切な方法は、Object.getPrototypeOfを使用することです(+ES6 では、意味的により明確なReflect.getPrototypeOfを使用できます) 。

function Pikaday() {}

console.log(
  Object.getPrototypeOf(new Pikaday()) === Pikaday.prototype
);

console.log(
  Reflect.getPrototypeOf(new Pikaday()) === Pikaday.prototype
);

コードの問題の 1 つは、getElementsByClassNameがこのクラスを持つノードのNodeList (配列ではない)を返すことです。

つまり、このリストをループして、各要素にハンドラーをアタッチする必要があります。

let nodes = document.getElementsByClassName('pika-year-label');
Array.from(nodes) // convert NodeList to an array so we can use forEach
  .forEach(node => {
    // attach a handler on each node
    node.onclick = function (){
      console.log("asfd");
    }
  });

// Side Note: You can also use array spread to convert the node list to an array
// [...nodes].forEach( ... )

または、すべての要素の共通の親にハンドラーをアタッチして、動作を委任します。

document.body.onclick = function(e) {
  if (e.target.classList.contains('pika-year-label')) {
    console.log("asfd");
  }
}

最後に、この関数を既存の関数のプロトタイプに追加するだけの場合は、そのプロトタイプのメソッドとして単純に定義する方法があります。

function Pikaday() {}

// define a method on the existing prototype
Pikaday.prototype.showYearPicker = function() {
  console.log('called');
};

let pikaday = new Pikaday();
pikaday.showYearPicker(); // <-- call the function on the prototype

于 2016-12-05T02:30:41.667 に答える