2017-04-04 4 views
0

かなり単純なバニラのJavascriptで問題があります。すべてのp要素をタグ名で取得し、それぞれにイベントハンドラをアタッチします。イベントハンドラは、色を赤に変更する関数を呼び出します。JavascriptのaddEventListenerがオブジェクトポインタのスコープを変更するのはなぜですか?

コールバック関数の外側elは、1-6という正しい要素を指します。しかし、ループの中では、javascriptの語彙変数スコープの性質にもかかわらず、常に最後のものを参照します。これはなぜですか、そして、内在する振る舞いを実装するためには何ができますか?

フィドル:https://jsfiddle.net/7j4bg68g/

<p>1 This is a test.</p> 
<p>2 This is a test.</p> 
<p>3 This is a test.</p> 
<p>4 This is a test.</p> 
<p>5 This is a test.</p> 
<p>6 This is a test.</p> 

...

function takeAction() { 
    this.style.color = 'red'; 
} 

var els = document.getElementsByTagName('p'); 
for (var i = 0; i < els.length; i++) { 
    var el = els[i]; 

    // logs els 1 to 6 as expected. 
    console.log(el.innerHTML); 

    el.addEventListener('click', function() { 

    // logs "6 This is a test.", and makes the last <p> tag red, 
    // regardless of which <p> element you click on. 
    console.log(el.innerHTML); 
    takeAction.call(el); 

    }, false); 
} 
+0

、これを試してみてください、 takeAction) ' –

答えて

2

これはあなたのコードの中であなたは "エル" に参照されている、ため閉鎖です。すべてのイベントハンドラはループ内で与えられた最後の値に変更された同じ変数elへの参照を持っています。 [i]を.addEventListener(「クリック」あなたの質問に問題の原因に対処していないが、あなたはコードを単純化し、単に `ELSにループ本体を変更することで問題を回避でき

function takeAction() { 
    this.style.color = 'red'; 
} 

var els = document.getElementsByTagName('p'); 
for (var i = 0; i < els.length; i++) { 
    var el = els[i]; 

    // logs els 1 to 6 as expected. 
    console.log(el.innerHTML); 
(function(elem){ 
    elem.addEventListener('click', function() { 

    // logs "6 This is a test.", and makes the last <p> tag red, regardless of which <p> element you click on. 
    console.log(elem.innerHTML); // logs "6 This is a test." 
    takeAction.call(elem); 

    }, false); 
})(el); 
} 
+1

構文を修正する必要があります。今は間違いでしょう。また、訂正されたコードは提示された問題に対する可能な解決策であるが、オペレータは事象ハンドラ内で単に「this」を使用できるので、不必要に冗長な解決策である。 –

+0

これは動作します: 'el.addEventListenerは({)(、機能を 'クリック' \t \t \t \t \t \tにconsole.log(this.innerHTML); \t \t \t \t \t \t takeAction.call(この); \t \t \t \t \t}、false); ' – kohloth

+0

IceBox:質問を編集しましたが、まだ構文エラーがあります。あなたのコードをテストしましたか? –

関連する問題