簡體   English   中英

在循環中使用 setTimeout

[英]using setTimeout inside a loop

下面是我的 HTML ocde

<div>6</div>
<div>2</div>
<div>7</div>
<div>5</div>
<div>9</div>
<div>4</div>
<div>8</div>
<div>1</div>
<div>3</div>

我希望 div 的文本顏色按照其內部文本的順序變為紅色。第一個<div>1</div>文本應顯示紅色,依此類推

到目前為止,我已經這樣做了-

var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
  for (var j = 0; j < divs.length; j++) {
    if (parseInt(divs[j].innerText, 10) == i + 1) {
      (function(index) {
        setTimeout(function() {
          divs[index].style.color = 'red';
        }, j * 1000);
      })(j);
    }
  }
}

當我調試時,循環中的值正確出現並且相應 div 的 css 已正確應用,但是當我運行代碼時,div 的內部文本按照我在 HTML 中定義的順序變為紅色。

您將超時設置為j * 1000並且j是 div 列表中的位置。

文本中的數字是i + 1而不是j 您需要在超時值中使用i + 1

嘗試這個:

divs[index].style.color = 'red';
    }, j * 1000);

應該:

divs[index].style.color = 'red';
    }, (i + 1) * 1000);

我不是...

 var divs = document.getElementsByTagName('div'); for (var i = 0; i < divs.length; i++) { for (var j = 0; j < divs.length; j++) { if (parseInt(divs[j].innerText, 10) == i + 1) { (function(index) { setTimeout(function() { divs[index].style.color = 'red'; }, (i + 1) * 1000); })(j); } } }
 <div>6</div> <div>2</div> <div>7</div> <div>5</div> <div>9</div> <div>4</div> <div>8</div> <div>1</div> <div>3</div>

真的沒必要把它復雜化。

如果您嘗試按順序突出顯示數字,則不需要兩個循環:

 var divs = document.getElementsByTagName('div'); for (var i = 0; i < divs.length; i++) { (function(index) { setTimeout(function() { divs[index].style.color = 'red'; }, divs[index].innerText * 1000); })(i); }
 <div>6</div> <div>2</div> <div>7</div> <div>5</div> <div>9</div> <div>4</div> <div>8</div> <div>1</div> <div>3</div>

一個循環,只需根據其內部編號為每個 div 設置超時。

與其讓它變得復雜並創建一個嵌套循環,不如創建一個只有一個循環的遞歸調用。 這將使您不會以不同的間隔一次創建所有超時。

通過在找到最小值之前過濾此列表,您可以為您必須迭代的每個項目將搜索減少一個項目。

 selectInOrder(document.getElementsByTagName('div')); function selectInOrder(elements) { if (elements.length > 0) { var item = minItem([].filter.call(elements, function(el) { return el.dataset.found === undefined; }), function(el) { return parseInt(el.innerText, 10); }); if (item) { item.dataset.found = true; setTimeout(function() { item.style.color = 'red'; selectInOrder(elements); }, 1000); } } } function minItem(items, itemFn) { var min = Number.POSITIVE_INFINITY; var item = null; for (var i = items.length - 1; i >= 0; i--) { var localMin = itemFn.call(items[i], items[i]); if (localMin < min) { min = localMin; item = items[i]; } } return item; }
 <div>6</div> <div>2</div> <div>7</div> <div>5</div> <div>9</div> <div>4</div> <div>8</div> <div>1</div> <div>3</div>

您可以通過以下方式簡化它:

 var item = 1; var divs = document.getElementsByTagName('div'); clr = setInterval(function() { for (var i = 0; i < divs.length; i++) { if (parseInt(divs[i].innerText, 10) == item) divs[i].style.color = 'red'; } item++; if (item > i) clearInterval(clr); }, 1000)
 <div>6</div> <div>2</div> <div>7</div> <div>5</div> <div>9</div> <div>4</div> <div>8</div> <div>1</div> <div>3</div>

使用setInterval每秒運行一次檢查,包括循環遍歷 div 並匹配索引(此處為項目)。 在每個間隔后增加索引。

好的,所以我查看了你的循環,我可以看到你把事情復雜化了很多。

評論:

  • 使用普通回調函數代替雙閉包:

    • 錯誤的:

       for( var i = ... ) { setTimeout((function(num) {return function(num) { ... };})(i), time) }
    • 正確的:

       for( var i = ... ) { setTimeout(myFunction, time, i); } function myFunction(num) { ... }
  • innerText不是標准的,所以它只適用於 Google 的 puppets
  • 你的內部循環對我來說不是很清楚 - 為什么不只使用一個循環

工作代碼

 var divs = document.getElementsByTagName('div'); for (var i = 0; i < divs.length; i++) { // innerText is not cross browser and not standard var number = parseInt(divs[i].innerHTML,10); // Debug console.log(number, divs[i].innerHTML); // As many seconds as div contents setTimeout(highlightDiv, 1000*(number), divs[i]); } // It's stupid to recreate function() {} foe every timeout // so I created standalone function instead function highlightDiv(div) { div.className = "timeout"; }
 .timeout { color: red; background-color: yellow; }
 <div>6</div> <div>2</div> <div>7</div> <div>5</div> <div>9</div> <div>4</div> <div>8</div> <div>1</div> <div>3</div>

嘗試這個

for(var i=0;i<divs.length;i++){
  var contentValue = parseInt(divs[j].innerText,10);
    setTimeout(function() { divs[index].style.color = 'red'; }, contentValue * 1000);   
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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