簡體   English   中英

setTimeout()在周期中,行為異常

[英]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()

由於要使用特定的參數調用該函數,因此可以使用閉包記錄ij的當前值:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM