如何使我的循环与 setTimeout 一起工作?

How to make my loop work with setTimeout?

正在另一个函数中调用 changeColor。我已经在没有循环的情况下尝试过了,它工作得很好。问题是它只会显示在一个盒子上。我试图让它显示在每个盒子上,但我 运行 陷入了死胡同。我已经尝试过 if 和 else if,它不会循环。我的代码中缺少什么?为什么它忽略循环?

function changeColor() {

    var flash = document.querySelector(".side1");

    for (var i = 0; i < flash.length; i++) {
        flash[i].style.backgroundColor = 'green'

            setTimeout(function () {
                flash[i].style.backgroundColor = 'yellow'
            }, 3000);


            setTimeout(function() {
                flash[i].style.backgroundColor = 'red'
            }, 10000);

    } 

}
setInterval(changeColor, 80000000);

document.querySelector 只有 return 是第一个匹配项,不是数组。 document.querySelectorAll 将 return 一个包含所有匹配项的数组。

EDIT 此外,正如@Drag13 在下面指出的那样,所有超时都将使用 i 的最终值,而不是您第一次设置时的值暂停。要解决此问题,您可以使用 let i = 0 而不是 var i = 0i 放入块范围,这意味着该块内的所有代码都将存在当前值,包括您的 setTimeout回调。

正如其他人所指出的,document.querySelector 仅在元素上 returns,而不是数组。您也有变量范围问题,可以使用 let 来限制范围,但这是该语言的一个相对较新的功能。如果兼容性是一个问题,您可能希望找到另一种解决方案,如 Patrick Evans 所建议的闭包。这是您在功能片段中的示例。我加快了速度并解决了 Patrick Evans 在评论中指出的范围问题。直到。

function changeColor() {
  var flash = document.querySelectorAll("div.flash")

  for (var i = 0; i < flash.length; i++) {
    flash[i].className = 'flash green'

    // create a closure which flashes yellow
    var flashYellow = (function() {
      var f = flash[i]
      return function() {
        f.className = 'flash yellow'
      }
    })()
    // create a closure which flashes red
    var flashRed = (function() {
      var f = flash[i]
      return function(){
        f.className = 'flash red'
      }
    })()

    setTimeout(flashYellow, 1000);
    setTimeout(flashRed, 2000);
  }
}
// change color immediately
changeColor();
// change color every three seconds after that
setInterval(changeColor, 3000);
div.flash {
  height: 25vh;
  width: 25vw;
}

div.green {
  background-color: green;
}

div.yellow {
  background-color: yellow;
}

div.red {
  background-color: red;
}
<div class="flash">text</div>
<div class="flash">other text</div>