3

の読み込み時に、内部Windowのすべての要素に関数をトリガーするイベントを追加する必要がありますが、関数をトリガーした要素ではなく、ステートメントの最後の要素のとを返します。関数をトリガーした要素のとを返したいと思います。DDQuote_ApponCLickLoremLoremnodeNameIdForLoremnodeNameId

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現在、任意の要素をクリックすると、Lorem常に最後の要素のnodeNameとが返されます。IdDD

Loremをトリガーした( )nodeNameのとを返す必要があります。IdControlControl[i]Lorem

これを実現するにはどうすればよいですか?

ありがとうございました!

4

3 に答える 3

5

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各イベント ハンドラー関数を宣言する時点で、各ループ反復でそのままの値が必要なため、各反復でこの値を取得する必要があります。宣言されるとすぐに実行される無名関数を使用することは、目的の値を取得するための優れたメカニズムです。

もう 1 つのポイントは、トピックから少し外れていますが、役立つかもしれませんが、イベントのキャプチャはすべてのブラウザー ( ahem、IE) でサポートされているわけではありませんが、イベントのバブリングはサポートされているということです。これにより、クロス ブラウザー Web アプリケーションの開発useCaptureにブール値フラグが実質的に役に立たなくなります。addEventListenerしたがって、使用しないことをお勧めします。

もう1つ、JavaScriptは通常、関数名と変数名にキャメルケースを使用します。Pascal ケーシングは、通常、コンストラクター関数 (オブジェクトを作成する関数) にのみ使用されます。

于 2010-04-07T22:13:43.707 に答える
3

外部の変数を参照する関数を作成すると、これらの参照はこの関数を呼び出すときに解決されます。

あなたの場合:

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

現在のカウンターのコピーをパラメーターとして取得する内部関数があることがわかります。この内部関数はそのコピーと共に存続するため、後で格納された innest 関数を呼び出すと、それを作成した関数の my_i の値が返されます -- クリア? :-)

これが閉鎖の素晴らしい世界です。最初にそれを取得するのに少し気が遠くなるかもしれませんが、それを取得したことを嬉しく思うので、グーグルで「javascriptクロージャー」を検索してください!

于 2010-04-07T22:42:15.967 に答える
2

これは、Russ Cam の回答のより明白な変形である可能性があります。

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]);
  }
};
于 2010-04-07T22:35:19.310 に答える