2017-05-06 54 views
0

下面的代码按预期工作。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引用的答案可能对许多人有所帮助,但对我个人来说并不是特别有用。

+0

对不起,我删除了我的答案,因为它是在黑暗中拍摄。自从我写Javascript以来已经有一段时间了。 – Carcigenicate

回答

0

正如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>

+0

谢谢,@AndyB。此解决方案确实可以防止控制台错误不幸的是,'myClass'被一次性添加到'mySelector'的每个实例中(在一秒延迟之后),而不是在每个延迟一秒后依次添加。如果这是有道理的。 感谢您的帮助,但。 –

+0

@DonkeyShame: 将setTimeOut时间改为1000+ 1000 * i而不是1000 – AndyB

+0

没错!谢谢!标记为答案。 –

0

js循环有一个简单的情况。原因js执行你的代码异步,变量i是更有效的索引mySelector。您可以使用let i而不是var i,或使用js关闭。 Here你可以找到更多关于这方面的信息。

相关问题