简体   繁体   English

在循环中使用 setTimeout

[英]using setTimeout inside a loop

Below is my HTML ocde下面是我的 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>

I want the div's text color to be red in the order of their inner text.First <div>1</div> text should display red color and so on我希望 div 的文本颜色按照其内部文本的顺序变为红色。第一个<div>1</div>文本应显示红色,依此类推

So far I have done this-到目前为止,我已经这样做了-

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

When I am debugging the values are coming correctly inside the loop and the css for the corresponding div is applied properly but when I am running the code the div's inner text is getting red color in the order I have defined in HTML.当我调试时,循环中的值正确出现并且相应 div 的 css 已正确应用,但是当我运行代码时,div 的内部文本按照我在 HTML 中定义的顺序变为红色。

You're setting the timeout to j * 1000 and j is the position in the list of divs.您将超时设置为j * 1000并且j是 div 列表中的位置。

The number in the text is i + 1 not j .文本中的数字是i + 1而不是j You need to use i + 1 in your timeout value.您需要在超时值中使用i + 1

Try this:尝试这个:

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

Should be:应该:

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

i not j...我不是...

 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>

Really no need to overcomplicate it.真的没必要把它复杂化。

If you're trying to highlight the numbers in order, you don't need two loops:如果您尝试按顺序突出显示数字,则不需要两个循环:

 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>

One loop, and simply set the timeouts for each div based on its inner number.一个循环,只需根据其内部编号为每个 div 设置超时。

Instead of making it complicated and making a nested loop, just create a recursive call with only one loop.与其让它变得复杂并创建一个嵌套循环,不如创建一个只有一个循环的递归调用。 This will make it so that you do not create all your timeouts at once, with varying intervals.这将使您不会以不同的间隔一次创建所有超时。

By filtering this list before finding the min, you reduce the search by one item for each item you have to iterate over.通过在找到最小值之前过滤此列表,您可以为您必须迭代的每个项目将搜索减少一个项目。

 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>

You can simplify it with:您可以通过以下方式简化它:

 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>

Use setInterval to run your check every second, which consists of looping over your divs and matching an index (item here).使用setInterval每秒运行一次检查,包括循环遍历 div 并匹配索引(此处为项目)。 Increment the index after every interval.在每个间隔后增加索引。

Ok so I looked on your loop and I can see you're over-complicating things a lot.好的,所以我查看了你的循环,我可以看到你把事情复杂化了很多。

Remarks:评论:

  • Instead of double closure, use normal callback function:使用普通回调函数代替双闭包:

    • Wrong:错误的:

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

       for( var i = ... ) { setTimeout(myFunction, time, i); } function myFunction(num) { ... }
  • innerText is not standard, so it only work in Google's puppets innerText不是标准的,所以它只适用于 Google 的 puppets
  • Your inner loop is not exactly clear to me - why not just use one loop你的内部循环对我来说不是很清楚 - 为什么不只使用一个循环

Working code工作代码

 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>

Try this尝试这个

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