2017-05-06 104 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你可以找到更多關於這方面的信息。

相關問題