1

要素の onClick イベントを動的に変更しようとしていますが、次のようなものがあります。

for (var i = 1; i < 5; i++)
{
    getElementById('element' + i).onclick = function() { existingFunction(i); return false; };
}

「existingFunction()」に渡される引数が、呼び出されるたびに i=4 の最終値であるという事実を除けば、すべて正常に動作しているようです。関数を onclick にバインドして、バインド時に i の値を使用する方法はありますか? 現時点で実行しているように見え、for ループで元の i を参照するのとは対照的です。

また、毎回匿名関数を作成せずに同じバインドを実行する方法はありますか? パフォーマンス上の理由から、各 onclick で「existingFunction」を直接参照できるようにするには?

乾杯、ヨン

4

4 に答える 4

4

変化する

for (var i = 1; i < 5; i++)
{
    getElementById('element' + i).onclick = function() { existingFunction(i); return false; };
}

for (var i = 1; i < 5; i++)
{
    getElementById('element' + i).onclick = createOneHandler(i);
}

function createOneHandler(number){  
    return function() {  
        existingFunction(number); 
    }  
}

そしてそれはうまくいくはずです。

ワーキングデモ

ここに良い説明があります

JavaScript、クロージャを理解するまでの時間

于 2009-11-17T04:16:42.920 に答える
1

i常に 4 であるため、スコーピングに問題があります。これを読むことをお勧めします。スコーピングは非常に重要な概念であるため、何が起こっているのかを確実に理解する必要があります。

より良いコードは

for (var i = 1; i < 5; i++)
{
    getElementById('element' + i).onclick = existingFunction;
}

onclick は引数を持つイベントを渡すので、どの要素がクリックされたかを知ることができます。

function existingFunction(event){
  // DO something here
}

イベントの詳細については、こちらをご覧ください。IE には他のブラウザーとまったく同じイベント モデルがあるため、それを処理する必要があります。

最後に、タスクを簡素化するため、JS フレームワーク (Jquery、ExtJS、DOJO、Prototype...) を使用することをお勧めします。

于 2009-11-17T04:25:16.407 に答える
1

投稿したコードは意図したとおりに機能するはずです。i=4 に関する問題は別の場所にあります。編集: これは間違っています。スコープの問題については rageZ が正しいです。

他の質問について:あなたができることは、冗長性をオフロードすることだけです

var f = function (i) { return function () { existingFunction(i); return false; } }
for (...) { document.getElementById(...).onclick = f(i); }

ところで、DOM 操作 (簡潔な構文) には jQuery のようなものを使用し、関数の構成にはおそらく Zeta ( http://codex.sigpipe.cz/zeta/ ) を使用する必要があります。

var f = compose(false_, existingFunction);
for (...) { $(...).click(f(i));
于 2009-11-17T04:17:00.183 に答える
0

万歳!再びループ クロージャです。詳細については、422784、643542、1552941などを参照してください

毎回匿名関数を作成せずに同じバインドを実行する方法はありますか?

はい、ECMAScript 第 5 版では次のようになりますfunction.bind

for (var i = 1; i < 5; i++)
    document.getElementById('element'+i).onclick= existingFunction.bind(window, i);

それまでの間、ブラウザーはまだ一般的にサポートしていないため、フォールバックとして匿名関数から構築された代替実装 (そのようなものについては、このコメントの下部をbind参照) にモンキー パッチを適用できます。

または、同じイベント ハンドラー関数をすべての要素に割り当てて、それを見て、this.idそれがどの要素番号であるかを確認します。

于 2009-11-17T04:58:39.943 に答える