0

よし、

私はこのように見えるものを持っています:

for (j = 0; j < btnArr.length; j++)
{
    var btn = document.createElement("button");
    btn.addEventListener("click", function() { press(this, j) }, false);
    div.appendChild(btn);
}

私の問題は、イベントが遅い時間に発生するjため、イベントの関数がトリガーされるまでにすでに値が変更されていることです。j関数が宣言されたときに、jそれ自体への参照ではなく、関数がの値を直接使用するようにしたい。

の2番目のパラメータが文字列の場合addEventListener、次のようになります。

btn.addEventListener("click", "function() { press(this, " + j + ") }", false);

誰かがそれが可能かどうか、そしてこれを行う方法を知っていますか?

少し調べてみましたが、ほんの数語で問題を正しく説明するのが難しいため、関連するものが見つかりません。

ちなみに、これはGreasemonkeyスクリプト用なので、.addEventListener()代わりに.onclick = (...)

4

4 に答える 4

2

あなたはただ文脈を壊す必要があります。それはたくさんの方法で行うことができますが、Function.bindは最もエレガントな私見です。Firefoxを使用しているので、bindがそこにあるはずです。

for (j = 0; j < btnArr.length; j++)
{
    var btn = document.createElement("button");
    btn.addEventListener("click", function(value) { press(this, value) }.bind(btn, j), false);
    div.appendChild(btn);
}

別のアプローチとして、ハンドラーを返す関数を記述します。

for (j = 0; j < btnArr.length; j++)
{
    var btn = document.createElement("button");
    btn.addEventListener("click", getHandler(j), false);
    div.appendChild(btn);
}

function getHandler(j) {
    return function() { press(this, j) };
}

さらに別のオプションは、button要素にプロパティを追加することです。

for (j = 0; j < btnArr.length; j++)
{
    var btn = document.createElement("button");
    btn.myValue = j;
    btn.addEventListener("click", function() { press(this, this.myValue); }, false);
    div.appendChild(btn);
}
于 2011-10-11T01:43:00.457 に答える
1

あなたはリスナーの閉鎖という古くからの問題にぶつかりました。次を使用できます。

btn.addEventListener("click", (function(x) {
                                 return function(){
                                    press(this, x) 
                                 };
                               }(j)), false);

また、一部のブラウザでのメモリリークを回避するために、要素の使用が終了したら、要素への参照を削除してください。

btn = null;

閉鎖を破る。SOにはこれに対する多くの答えがあります。bindを使用できますが、すべてのブラウザで使用できるわけではありません。

于 2011-10-11T01:45:35.217 に答える
1

btnはオブジェクトであり、いつでも独自のプロパティを追加して、後でそれらにアクセスできます。

for (var j = 0; j < btnArr.length; j++)
{
    var btn = document.createElement("button");
    btn.index = j;
    btn.addEventListener("click", function() { press(this, this.index) }, false);
    div.appendChild(btn);
}

http://jsfiddle.net/Kai/Y2KaZ/を参照してください

于 2011-10-11T01:47:33.103 に答える
0

そのような字句スコープのルールを変更することはできません。できることは、ヘルパー関数を作成すると、新しいバインディングが喜んで作成されるという事実を利用することです。

function make_handler(i){
    //you can use j here as well instead of i
    //I'm just avoiding shadowing for didactic reasons...
    return function() { press(this, i) };
}

for (j = 0; j < btnArr.length; j++)
{
    var btn = document.createElement("button");
    btn.addEventListener("click", make_handler(j), false);
    div.appendChild(btn);
}
于 2011-10-11T01:44:52.720 に答える