0

私は JavaScript の初心者で、次の問題を回避する方法が思いつきません。この例では Mootools を使用していますが、これは Mootools に関する質問ではありません。

for (var i = 0; i < 5; i++) {
    myElement[i].addEvent('click', function () { otherFunction(i); });
}

誰かが myElement をクリックするたびに、otherFunction が呼び出されます (良い) が、5 が渡されます (悪い)。これは、ループが終了した後(要素をクリックしたとき)にアクセスするためであることはわかっていますが、単調なものを除いて、一生考えることはできません

switch(i) {
    case 1: myElement[i].addEvent('click', function () { otherFunction(1); }); break;
    case 2: myElement[i].addEvent('click', function () { otherFunction(2); }); break;
    // ...
}

もっと良い方法があるに違いない...明らかな何かが欠けている気がする

更新: myElement に [i] インデックスを追加しました (おっと)

ありがとう、キャメロン

4

2 に答える 2

2

あなたのコードはクロージャーの例です。無名関数はiの最後の値を参照します。これは、関数が呼び出されたときに後で使用するためにその外側のスコープを効果的に保持しているためです。

これを修正する方法の 1 つを次に示します。

function getClickHandler(i)
{ 
   return function () { otherFunction(i); }
}

for (var i = 0; i < 5; i++) {
    myElement.addEvent('click', getClickHandler(i));
}

これにより、クロージャーの作成が別のスコープに移動し、 iの各値が「保持」されます。

もう 1 つの方法は、各要素に割り当てることができる 1 つのクリック ハンドラーを用意し、イベント オブジェクトからクリックされたものを特定することです (これらのハンドラーをさまざまな要素にアタッチすると仮定しますが、コードでは複数のハンドラーが必要であることが示されています)同じ要素ですが、少し奇妙です:)

于 2009-02-16T15:41:48.827 に答える
1

1 つの要素に対して 5 つのクリック ハンドラーが必要な理由を質問するコメントに同意しますが、目的を達成するにはクロージャーを使用する必要があります。

JavaScript チュートリアルに関するこのチュートリアルをご覧ください。

更新: いくつかのコード/構文サンプルについては、イベント ハンドラーのクロージャーの使用というまったく同じテーマで私がここで尋ねたこの質問を見てください。

于 2009-02-16T15:41:31.370 に答える