2

私はこのようなJavaScriptコードを持っていますが、これは常に問題を引き起こします

    for(var i=1;i<9;i++){
        document.getElementById('element'+i).onclick=function(){
             theFunc(i)
        }
    }

正しい要素を選択し、onclick を追加します。しかし、コンソールに入力する document.getElementById('element1").onclickと返されますtheFunc(i)(not theFunc(1))

したがって、どの要素がクリックされても、常に呼び出されますtheFunc(9)(最後に i は 9 です)。

コードの何が問題になっていますか?

4

3 に答える 3

5

あなたが発見したように、あなたのイベントハンドラー関数には、その値のコピーではなく、への永続的な参照があります。i

それを防ぐには、変更されない他の何かの上に関数を閉じます。

for(var i=1;i<9;i++){
    document.getElementById('element'+i).onclick=makeHandler(i);
}

function makeHandler(index) {
    return function() {
        theFunc(index);
    };
}

makeHandlerの値indexコピーであるを閉じる関数を作成するため、ループが継続しても変化しません。各イベント ハンドラは独自のを取得します。i index

とは言っても、事実上同一の一連のイベント ハンドラー関数を作成するということは、通常、少し再設計して 1 つのハンドラー関数のみを使用できることを意味します。この場合、たとえば、次のようにできます。

for(var i=1;i<9;i++){
    document.getElementById('element'+i).onclick=theHandler;
}

function theHandler() {
    func(parseInt(this.id.replace(/\D/g, ''));
}

...要素から使用する値を取得しますid

もう 1 つのアプローチはdelegationです。ここでは、実際にclick先祖要素 (これらすべての elementX に共通する要素) にイベントをフックし、クリックが発生したときにevent.targetとその祖先を見て、何をすべきかを確認します。

于 2013-08-06T14:36:20.280 に答える
1

TJ Crowder の答えは、問題を回避する最善の方法です。クロージャーで発生しているこの「問題」は、多くの言語の仕様によるものであり、スコープと呼ばれます。

ここでは、JavaScript のさまざまなスコープ (クロージャーを含む) とその使用方法について説明します。 http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/

于 2013-08-06T14:42:44.490 に答える