2017-05-09 95 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

相关问题