なぜ「の(){}」ステートメントの最後の要素ではなく、それ自体に意味コレクション内の各要素にイベントを追加することはできません

StackOverflow https://stackoverflow.com/questions/2596284

質問

Windowの負荷では、DD内部のすべてのQuote_App要素はonCLickイベントがトリガ機能Loremが、しかし、Loremはむしろ機能をtrigged素子よりもnodeName文で最後の要素のIdForを返すことを追加している必要があります。私はLorem機能をトリガー要素のnodeNameIdを返すようにしたいでしょう。

function Lorem(Control){

/*     this.Control=Control; */
    this.Amet=function(){
        return Control.nodeName+"\n"+Control.id;
    };

};

function Event(Mode,Function,Event,Element,Capture_or_Bubble){
    if(Mode.toLowerCase()!="remove"){
        if(Element.addEventListener){
            if(!Capture_or_Bubble){
                Capture_or_Bubble=false;
            }else{
                if(Capture_or_Bubble.toLowerCase()!="true"){
                    Capture_or_Bubble=false;
                }else{
                    Capture_or_Bubble=true;
                };
            };
            Element.addEventListener(Event,Function,Capture_or_Bubble);
        }else{
            Element.attachEvent("on"+Event,Function);
        };
    };
};

function Controls(){
    var Controls=document.getElementById("Quote_App").getElementsByTagName("dd");
    for(var i=0;i<Controls.length;i++){

        var Control=Controls[i];

        Event("add",function(){

            var lorem=new Lorem(Control);
            lorem.Control=Control;
            alert(lorem.Amet());

        },"click",Controls[i]);

    };
};

Event("add",Controls,"load",window);

現在、あなたは常に最後DD要素のLoremnodeNameを返す任意のId要素DDをクリックします。

LoremトリガnodeNameことIdControl)のControl[i]Loremを返す必要があります。

私はこれが起こることについてに行くにはどうすればよい?

ありがとうございます!

役に立ちましたか?

解決

あなたは各ループの反復でiの値をキャプチャするためにイベントハンドラをアタッチしているループ内でクロージャを必要としています。

  for(var i=0;i<Controls.length;i++) {   
    (function() {
        var Control=Controls[i];

        Event("add",function(){

            var lorem=new Lorem(Control);
            lorem.Control=Control;
            alert(lorem.Amet());

         },"click",Controls[i]);
    })();
  };

ここで私には、JavaScriptの良い友人、自己呼び出す無名関数を使用して上記の閉鎖を作成しました。

閉鎖が必要な理由は、それなしで、任意のイベントハンドラ関数が実行された時点でiの値は、我々が望むものを、最後のループ反復でiの値ではないだろうということです。それは、各ループ反復であると私たちは、このように私たちは、各反復で、この値をキャプチャする必要が、我々はそれぞれのイベントハンドラ関数を宣言した時点で、iの値を求めています。匿名関数を使用すると、すぐにそれが宣言だとして実行が所望の値を取得するための優れたメカニズムであること。

もう一つのポイントは、それはあなたを助けることが少しオフトピックしかし、そのイベントのキャプチャはすべてのブラウザでサポートされていません(のエヘンの、IE)が、イベントバブリングがあります。これは、効果的にクロスブラウザのWebアプリケーションを開発するためのuseCaptureaddEventListenerブールフラグがかなり無用になります。私はそのためにそれを使用しないようお勧めする。

もう一つは、JavaScriptは一般的に、関数名や変数名にキャメルケースを使用しています。パスカルケーシングは一般のみコンストラクタ関数(オブジェクトを作成する機能)のために使用されます。

他のヒント

あなたが外でそれの変数を参照する機能を作成すると、

、これらの文献は、この関数を呼び出す時に解決されます。

あなたのケースでは、

var functions = [];
function outer() {
    for (var i = 0; i < N; i++) { // <------------
        functions[i] = function() { //            |
            alert(i); // <-- this 'i' refers to this one
        }
    } // At the end of the for loop, i == N (or N+1?)
}
functions[x](); // Will show N (or N+1)
// because that's the current value of i in the outer function
// (which is kept alive just because something refers to it)

あなたがやりたいことは例えば、後の評価のために、ループの各段階で「I」の値をキャプチャです:ます。

var functions = [];
function outer() {
    for (var i = 0; i < N; i++) { // <---------------------------------------
        functions[i] = (function(my_i) { // <----                            |
            return function () { //              |                           |
                alert(my_i); // my_i refers to this which is a copy of 'i' there
            }
        }(i)); // run function(with my_i = the i at each step of the loop)
    }
}
functions[x](); // Will show x

あなたは、パラメータとして、現在のカウンタのコピーを取得し、内部関数があります見ることができます。そのコピーで生きているこの内部機能の滞在、それを作成した機能のmy_iの保存された関数が返すinnest値への以降の呼び出しそう - クリア? : - )

このクロージャの素晴らしい世界です。そう行くと死ぬまで「JavaScriptのクロージャを」グーグル、それは心曲げまずそれを得るためのビットを取るかもしれないが、その後、あなたは喜んでいるよ!

このはラスカムの答えのより明白な変異体であってもよい。

function Controls() {
  var Controls = document.getElementById("Quote_App").getElementsByTagName("dd");

  var createHandlerFor = function(CurrentControl) {
    return function() {
      var lorem=new Lorem(CurrentControl);
      lorem.Control=CurrentControl;
      alert(lorem.Amet());
    }
  };

  for (var i=0; i<Controls.length; i++) {
    Event("add", createHandlerFor(Controls[i]), "click", Controls[i]);
  }
};
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top