For循环与setTimeout不按预期方式工作
下面的代码按预期工作。For循环与setTimeout不按预期方式工作
var mySelector = document.querySelectorAll('.mySelector');
var myFunction = function() {
for (var i = 0; i < mySelector.length; i++) {
mySelector[i].classList.add('myClass');
}
}
但是,此代码生成错误:“遗漏的类型错误:无法读取属性未定义‘班级列表’”
var mySelector = document.querySelectorAll('.mySelector');
var myFunction = function() {
for (var i = 0; i < mySelector.length; i++) {
setTimeout(function(i){
mySelector[i].classList.add('myClass');
}, 1000);
}
}
我敢肯定,有一个很简单的解释这是为什么,但我不知道。
为什么?
更新:新代码的参数从setTimeout函数删除
var mySelector = document.querySelectorAll('.mySelector');
var myFunction = function() {
for (var i = 0; i < mySelector.length; i++) {
setTimeout(function(){
mySelector[i].classList.add('myClass');
}, 1000);
}
}
更新2:
Barmar认为这是另一个问题的精确副本:JavaScript closure inside loops – simple practical example
我承认,这是一般类似的,Barmar联系的答案可能可以帮助那些在我面临的问题上有更多JavaScript体验的人。但我认为我的问题不同于以自己的条件保持开放,原因如下:(1)我的案例更简单,正确的答案可能有利于技能较低的JavaScript实践者(如我),(2)我特别与setTimeout有关,因为它与for循环有关。再次,我会批准Barmar引用的答案可能对许多人有所帮助,但对我个人来说并不是特别有用。
正如Carcigenicate所说,你无法访问我。以下将仅打印未定义。
var mySelector = document.querySelectorAll('.mySelector');
var myFunction = function() {
for (var i = 0; i < mySelector.length; i++) {
setTimeout(function(i){
console.log(i);
}, 1000);
}
}
myFunction();
<div class='mySelector'></div>
<div class='mySelector'></div>
<div class='mySelector'></div>
<div class='mySelector'></div>
<div class='mySelector'></div>
试试这个:
var mySelector = document.querySelectorAll('.mySelector');
var myFunction = function() {
for (var i = 0; i < mySelector.length; i++) {
setTimeout(addClass(i), 1000);
}
}
myFunction();
function addClass(i) {
return function() {
mySelector[i].classList.add('myClass');
}
}
<div class='mySelector'>1</div>
<div class='mySelector'>2</div>
<div class='mySelector'>3</div>
<div class='mySelector'>4</div>
<div class='mySelector'>5</div>
谢谢,@AndyB。此解决方案确实可以防止控制台错误不幸的是,'myClass'被一次性添加到'mySelector'的每个实例中(在一秒延迟之后),而不是在每个延迟一秒后依次添加。如果这是有道理的。 感谢您的帮助,但。 –
@DonkeyShame: 将setTimeOut时间改为1000+ 1000 * i而不是1000 – AndyB
没错!谢谢!标记为答案。 –
对不起,我删除了我的答案,因为它是在黑暗中拍摄。自从我写Javascript以来已经有一段时间了。 – Carcigenicate