2017-04-04 75 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

雖然不是解決你的問題的問題的原因,你可以簡化代碼,並通過簡單的循環體改變爲'ELS [I]閱讀進度(「點擊」防止問題, takeAction)' – 2017-04-04 16:22:34

回答

2

這是因爲封閉的,在你的代碼中所引用到 「厄爾尼諾」。所有的事件處理程序都會引用相同的變量el,並將其更改爲循環中給出的最後一個值。 試試這個,

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

你需要修正你的語法。它現在會出錯。雖然正確的代碼可能是解決問題的一種可能的解決方案,但它是一個不必要的詳細解決方案,因爲OP可以在事件處理程序中簡單地使用this。 – 2017-04-04 16:19:22

+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

冰箱:你編輯的問題,但仍然有語法錯誤。你測試了你的代碼嗎? – 2017-04-04 16:27:22