0

これに関連していると思われるいくつかの質問を見つけましたが、私の理解の範囲では、私のものは異なるので、ここに行きます. コードを大幅に簡素化し、1行をコメントに置き換えましたが、概念は同じです...

function myFunction(options) {
    var button;
    options.widgets.forEach(function (w) {
        button = document.createElement("button");
        //add button to the DOM
        aListOnMyPage.addEventListener("selectionchanged", function (args) {
            var a = button;
        });
    });
}

そこで、ウィジェットごとに新しいオブジェクトを作成し、作成した DOM 要素 (ボタン) を関数が参照する必要があるページのリストにイベント リスナーを追加します。私が見ている動作は、イベントリスナーを作成した時点でボタンが正しく設定されていることですが、リスナーのイベントが発生すると、ボタンは常に最後に作成したボタンへの参照になります。遅いからかもしれませんが、なぜこのように振る舞うのか頭を悩ませることはできません。誰かが私のためにこれを明確にすることができますか?

4

2 に答える 2

3

確かにできます。

ここでの問題は、実際にはスコープです。あなたが書いたコードを見てみましょう:

function myFunction(options) {
    var button;
    options.widgets.forEach(function (w) {
        button = document.createElement("button"); // UH-OH...
        //add button to the DOM
        aListOnMyPage.addEventListener("selectionchanged", function (args) {
            var a = button;
        });
    });
}

うーん、お気づきですか?that buttonshould equalを宣言しましたが、キーワードdocument.createElement("button")を使用していないため、複数のローカル変数ではなく、1 つのグローバル変数を宣言しています。varつまり、ループが実行されるたびに、その 1 つのグローバル変数がリスナーによって参照されているため、問題が発生します。

次のように、ここで必ずローカル変数を使用してください。

function myFunction(options) {
    options.widgets.forEach(function (w) {
        var button = document.createElement("button"); 
        //add button to the DOM
        aListOnMyPage.addEventListener("selectionchanged", function (args) {
            var a = button;  
        });
    });
}

これにより、状況が大幅に改善されるはずです。少なくとも、あなたが一歩前進するのに役立つことを願っています。幸運を祈ります。

于 2012-08-25T06:49:06.283 に答える
1

クロージャーが原因でこの問題に直面していると思います。全体で使用されるボタン変数myFunctionは同じです。すべての変更は参照の変更であるため、変数の宣言を匿名関数内に変更すると、この問題が解決するはずです。

function myFunction(options) {
    //var button;
    options.widgets.forEach(function (w) {
        var button = document.createElement("button");
        //add button to the DOM
        aListOnMyPage.addEventListener("selectionchanged", function (args) {
            var a = button;
        });
    });
}

この変更により、forEach別のbutton変数を持つ無名関数が提供されます。

于 2012-08-25T06:55:16.807 に答える