在循环中使用setTimeout

时间:2015-11-16 15:52:12

标签: javascript

下面是我的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中定义的顺序变为红色。 / p>

7 个答案:

答案 0 :(得分:3)

您将超时设置为j * 1000j是div列表中的位置。

文字中的数字为i + 1而不是j。您需要在超时值中使用i + 1

答案 1 :(得分:1)

试试这个:

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

应该是:

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

我不是......

&#13;
&#13;
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);
    }
  }
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

真的不需要过度复杂化。

如果您尝试按顺序突出显示数字,则不需要两个循环:

&#13;
&#13;
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);
}
&#13;
<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>
&#13;
&#13;
&#13;

一个循环,只需根据内部数字设置每个div的超时。

答案 3 :(得分:0)

只需创建一个只有一个循环的递归调用,而不是使其变得复杂并形成嵌套循环。这将使您不会一次创建所有超时,并且间隔时间不同。

通过在找到分钟之前过滤此列表,您可以针对每个必须迭代的项目减少一个项目的搜索。

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>

答案 4 :(得分:-1)

您可以使用以下方式简化它:

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并匹配索引(此处为项目)。每个间隔后增加索引。

答案 5 :(得分:-1)

好的,所以我看了你的循环,我可以看到你过度复杂化了很多东西。

说明:

  • 使用普通回调函数代替双重闭包:

    • 错误:

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

      for( var i = ... ) {
         setTimeout(myFunction, time, i);
      }
      function myFunction(num) { ... }
      
  • innerText不标准,因此仅适用于Google的木偶
  • 你的内循环对我来说并不是很清楚 - 为什么不使用一个循环

工作代码

&#13;
&#13;
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";    
}
&#13;
.timeout {
  color: red;
  background-color: yellow;  
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 6 :(得分:-2)

试试这个

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