2017-05-06 17 views
0

以下のコードは、期待どおりに動作します。setTimeoutが期待通りに機能しないForループ

var mySelector = document.querySelectorAll('.mySelector'); 
var myFunction = function() { 
    for (var i = 0; i < mySelector.length; i++) { 
    mySelector[i].classList.add('myClass'); 
    } 
} 

しかし、このコードはエラーが発生:「キャッチされない例外TypeError:プロパティを読み取ることができません 『をCLASSLIST』未定義の」

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); 
    } 
} 

私はそれがある理由は非常に簡単な説明があります確信しているが、私はそれを知らない。

なぜですか?

UPDATE: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); 
    } 
} 

UPDATE 2:私はそれが一般的にあることを認めるJavaScript closure inside loops – simple practical example

Barmarが、これは別の質問の正確な複製ことを示唆しましたBarmarとリンクされた答えはおそらく私が直面している苦境よりも多くのJavaScript経験を持つ人を助けることができます。しかし、私の質問は、以下の理由から、それ自身の条件で開いたままにするには十分に異なると思います。(1)私のケースは簡単で正解は自分自身のような熟練したJavaScript実践者にとって利益をもたらすだろう。 forループに関連するsetTimeoutに関係します。また、私は、Barmarが参考にした答えが多くの人に役立つことを認めますが、個人的にはそれほど役に立ちません。

+0

それは暗闇の中でのショットだったので申し訳ありませんが、私は私の答えを削除します。私はJavascriptを書いて以来、しばらくしてきました。 – Carcigenicate

答えて

0

カルシゲネイトが述べたように、私にはアクセスできません。以下は、定義されていないものを出力するだけです。

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'は、それぞれ1秒遅れて順次追加されるのではなく、一度に(1秒遅れて) 'mySelector'の各インスタンスにすべて追加されます。それが意味をなさないならば。 ご協力いただきありがとうございます。 –

+0

@DonkeyShame: setTimeOutの時間を1000の代わりに「1000 + 1000 * i」に変更してください。 – AndyB

+0

うん、やったよ!ありがとう!答えとしてマーク。 –

0

jsループでは単純な状況があります。原因jsはコードasyncを実行するため、変数iは有効なインデックスmySelector以上です。 var iの代わりにlet iを使用するか、js closuresを使用します。 Hereこれについて詳しくは、こちらをご覧ください。

関連する問題