2017-05-09 38 views
3

我正在處理一個非常簡單的應用程序。當用戶懸停在任何列表項目(li)上時,文本顏色將變爲綠色,當鼠標移出時,它會變回黑色。作爲參數的匿名函數的作用域

爲什麼我們不能在以下一段代碼中使用lis[i]而不是this關鍵字?

var lis = document.querySelectorAll('li'); 
var i = 0; 
for(; i < lis.length; i++){ 

    lis[i].addEventListener('mouseover', function(){ 

    this.style.color = 'green'; 

    }); 
    lis[i].addEventListener('mouseout', function(){ 

    this.style.color ="black"; 
    }); 
}; 

回答

2

在調用函數時,循環已經完成。變量只有一個i,該函數始終會看到其當前值。所以如果你在函數中使用i,你會看到它的值爲lis.length

有辦法繞過它。如果你可以使用ES2015(可能通過transpiler),那麼你可以這樣寫:

const lis = document.querySelectorAll('li'); 
for(let i = 0; i < lis.length; i++){ 

    lis[i].addEventListener('mouseover',() => lis[i].style.color = 'green'); 
    lis[i].addEventListener('mouseout',() => lis[i].style.color ="black"); 
}; 

,現在你必須每輪循環的不同i

或者在舊代碼中,您可以將循環體推送到另一個函數並將i作爲參數傳入。具有結合不同的變量每個事件的相同的效果:

var lis = document.querySelectorAll('li'); 

var _loop = function _loop(i) { 

    lis[i].addEventListener('mouseover', function() { 
     return lis[i].style.color = 'green'; 
    }); 
    lis[i].addEventListener('mouseout', function() { 
     return lis[i].style.color = "black"; 
    }); 
}; 

for (var i = 0; i < lis.length; i++) { 
    _loop(i); 
} 

(這是自動由巴別從ES2015例如我上面給所產生的代碼)

3

當回調函數將被執行,由於循環,i變量將具有值lis.length,導致lis[i]的值爲undefined

你可以做的是使用forEach函數。

var lis = document.querySelectorAll('li'); 
 
lis.forEach(function (li) { 
 
    li.addEventListener('mouseover', function(){ 
 
    li.style.color = 'green'; 
 
    }); 
 
    li.addEventListener('mouseout', function(){ 
 
    li.style.color ="black"; 
 
    }); 
 
});
<ul> 
 
    <li>First LI</li> 
 
    <li>Second LI</li> 
 
</ul>

+0

事實上,'''i'''仍然會被定義,但卡在for循環的最後一個值(在這種情況下,lis.length,使得'''lis [i]'''undefined)。這是由於Javascript關閉。見@鄧肯的答案。 –

+1

@MichaelYang謝謝指出,我更關注解決問題的根源 – Erazihel

+1

當然 - 你的解決方案非常好!我只想指出:-) –

-1

您可以使用 「e.srcElement」 來獲得當前的目標是這樣

let lis = document.querySelectorAll('li'); 
 

 
for (let i = 0; i < lis.length; i++) { 
 
    lis[i].addEventListener('mouseover', function(e){ 
 
    e.srcElement.style.color = 'green'; 
 
    }) 
 
    lis[i].addEventListener('mouseout', function(e){ 
 
    e.srcElement.style.color = 'black'; 
 
    }) 
 
}
<ul> 
 
    <li>First LI</li> 
 
    <li>Second LI</li> 
 
</ul>

+0

他們可以,但這與他們問的問題無關 – Quentin

相關問題