[英]setTimeout() in cycle, strange behaviour
伙計們! 我是JavaScript的新手。 我編寫了第一個程序,並且已經習慣了它的行為:
var elements = document.getElementsByTagName("img");
for (var i = 0; i < elements.length; i++) {
if (i % 2 == 0) {
elements[i].src = "img.jpg";
for (var j = 0; j <= 1; j += 0.1) {
setTimeout(increase_opacity(elements[i], j), 2000);
// setTimeout(alert(j), 2000);
}
}
}
function increase_opacity(element, opacity) {
element.style.opacity = opacity;
}
我看不到不透明度發生了變化,但是在調試器中卻發生了,因此setTimeout
不能正常工作。 如果我取消注釋// setTimeout(alert(j), 2000);
我可以在每個循環步驟中看到不透明度變化和警報消息。 這是為什么?
setTimeOut接受一個函數,而您正在做的就是將對call_opacity的調用的結果傳遞給它。 下面的代碼應該為您工作。 請注意,如何在匿名函數定義中包裝crease_opacity。
var elements = document.getElementsByTagName("img");
for (var i = 0; i < elements.length; i++) {
if (i % 2 == 0) {
elements[i].src = "img.jpg";
for (var j = 0; j <= 1; j += 0.1) {
(function(element, opacity) {
setTimeout(function() { increase_opacity(element, opacity) } , 2000);
})(elements[i], j);
// setTimeout(alert(j), 2000);
}
}
}
這是有關setTimeOut的文檔http://www.w3schools.com/jsref/met_win_settimeout.asp
您需要將一個函數傳遞給setTimeout()
。 你在做什么是呼叫increase_opacity
立即然后返回值傳遞給setTimeout()
由於要使用特定的參數調用該函數,因此可以使用閉包記錄i
和j
的當前值:
setTimeout((function(a, b) {
return function() {
increase_opacity(a, b);
};
})(elements[i], j), 2000);
您是否知道setTimeout()
不是阻塞調用? 您的腳本不會在setTimeout()
函數處停止,而是繼續執行。 所以這是這里發生的事情:
1)您的代碼開始循環;
2)輸入setTimeout()
,它將啟動計時器並繼續運行;
3)對每個元素重復步驟2; (請注意,步驟2和3在幾毫秒內執行)
4)所有計時器到期,所有指令一次全部執行。
為了避免這種情況,您應該編寫如下內容:
var elements = document.getElementsByTagName("img");
for (var i = 0; i < elements.length; i++) {
if (i % 2 == 0) {
elements[i].src = "img.jpg";
setTimeout(function(){increase_opacity(elements[i],0);}, 2000);
}
}
function increase_opacity(element, opacity) {
element.style.opacity = opacity;
if (opacity < 1) setTimeout(function(){increase_opacity(element, opacity+0.1);},2000);
}
注意:在處理setTimeout()
,應在使用參數調用函數時避免使用該符號。 您應該始終使用此命令:
setTimeout(function(){yourFunctionName(arg1, arg2, arg3);});
NB 2: setTimeout(alert(j),2000);
甚至沒有等待2秒鍾出現。 就像我在上面說的那樣,在處理setTimeout()
時應使用匿名函數。 正因為如此,它可能給人以它正在工作的印象,但這是IMO的一種故障。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.