0

私はいくつかの形式(動的に作成)とHTMLページを持っているので、私は配列にJSでそれらを取得した後、私はこのように、それぞれにEventListenerを追加機能中checkAllFilled私はいくつかのことをする。JS addEventListenerを引数

問題ではなくcheckAllFilled(2)を呼び出す、私は(forms[0]からforms[6]まで)7つのフォームを持っていると私はforms[2]上で作業している場合、それは常にcheckAllFilled(7)と呼ばれているということです。これは、変数iがforループの最後の値に設定されたようです。

どうすればよいですか?

ありがとうございます!

+0

から聞かせて使用することです変数。 ( 'var i = 0') –

答えて

2

もう一つの方法は、ただのECMAScript 2015 @Utkanosはあなた `i`を宣言持っている必要があります+言っ

for(let i=0; i < forms.length; i++) { 
    forms[i].addEventListener('change', function(){ 
     checkAllFilled(i); 
    }); 
} 
+0

これは素晴らしい解決策です:)ありがとう! – Ommadawn

4

ループの最後の値に変数 "i"が設定されているようです。

これはまさに起きていることです。

考えてみてください。 forループが終了した後、イベントハンドラが後で実行されます。その時点で、変数にはループが残した値があります。したがって、イベントは常に同じ単一値を報告します。

代わりに、反復値をクロージャでバインドする必要があります。いくつかの方法があります。 1つは直ちに実行される関数(IEF)を介して行われます。

forms[i].addEventListener('change', (function(i) { return function(){ 
    checkAllFilled(i); 
}; })(i)); 

反復値を関数変数としてIEFに渡します。このようにして、クロージャを介してハンドラに渡されます。それはreading up on theseの価値があります。

+0

explanaitonと参考に感謝します:)しかし、動作しません! :( – Ommadawn

+0

IIFは渡された引数を取る必要があり、これは 'i'の代わりに' checkAllFilled'を呼び出すときに使用する必要があります。このコード例では、元のコードとは何も変わりません。 –

+0

Typo - IEF引数として 'i'を逃しました解決して動作します[Fiddle](https://jsfiddle.net/) – Utkanos

1

これらのリスナー(すべて同じ名前)を生成してから最後のものを呼び出すので、常に最後に生成されたイベントリスナーを呼び出すことになります。

ここでの最適な解決策は、カウンタ値iに基づいてイベントを処理する関数の名前を割り当てることです。代わりにforループの

1

使用forEach()

var forms = document.getElementsByTagName('form'); 

[].slice.call(forms).forEach(function(form, i) { 
    form.addEventListener('change', function(){ 
     checkAllFilled(i); 
    }); 
}); 
関連する問題