2013-12-14 11 views
8

私はこのコードを持っている:addEventListener、for()、index。閉鎖の使い方は?

var items = this.llistat.getElementsByTagName('a'); 

for(var i = 0; i < items.length; i++){  
    items[i].addEventListener('click', function(event) { 
    alert(i); 
    }, items[i]); 
} 

イベントは聞いているが、そこ3項目があると警告がオールウェイズ、要素(それはインデックスを尊重していない)のいずれかに3を印刷

items[i]は閉鎖として仕事をしてはいけませんか?

ありがとうございました!

+0

addEventListener' '[三番目の引数](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener)は、イベントリスナーがキャプチャの優先順位を取得するかどうかを示すブール値です(キャンセル可能にするなど)。それは 'this'値を指定しません。 – apsillers

+0

関連する[Javascriptの悪名高いループの問題?](http://stackoverflow.com/questions/1451009/javascript-infamous-loop-problem)。 –

答えて

9

:あなたが結合時には、ない「I」変数に、その値にバインドされた新しい関数を作成する必要があります。

var items = this.llistat.getElementsByTagName('a'); 

for(var i = 0; i < items.length; i++) { 
     items[i].addEventListener('click', listener.bind(null, i)); 
} 

function listener(index) { 
     alert(index); 
} 
+0

あなたのanserのおかげで、これは動作します。それは異種機能のみを使用している可能性がありますか?ちょうど好奇心.. ..ありがとう! –

+0

ようこそ。リスナーの内部に格納されている関数は匿名です。この中間変数を作成したくない場合は、addEventListenerの内部で、その値で 'listener'を置き換えてください。しかし、私はこれがもっと簡単に理解できると思う。 – GameAlchemist

+0

Javascriptインタプリタは最適化しないので、 'function listener(index){return function(){...};を定義する方が効率的です。 }ループの外側に 'items [i] .addEventListener( 'click'、listener(i)); 'という単一の文があります。この効率は、外部関数を一度定義することによって生じます。上記のように、外部関数はループの繰り返しごとに定義(および実行)されます。 –

7

いいえ、addEventListenerの3番目の引数はuseCaptureです。詳細については、MDNを参照してください。

しかし、あなたが使用することができます。

for(var i = 0; i < items.length; i++){ 
    (function(i){ 
     items[i].addEventListener('click', function(event) { 
      alert(i); 
     }, false); 
    })(i); 
} 

または

var handler = function(event) { 
    var i = items.indexOf(this); 
    alert(i); 
}; 
for(var i = 0; i < items.length; i++){ 
    items[i].addEventListener('click', handler, false); 
} 

最初のものは、各要素の新しいイベントハンドラを作成し、それはより多くのメモリを必要とします。 2番目のイベントリスナーは同じイベントリスナーを再利用しますが、indexOfを使用するため、処理が遅くなります。

古典閉鎖問題だ