我可以在setInterval中插入多个setTimeouts吗?

时间:2017-11-20 08:07:42

标签: javascript html settimeout setinterval

我刚开始学习JavaScript,现在,我正在制作一个红色,绿色和橙色的虚拟交通信号灯。我想通过向外部添加setInterval来制作一个循环。这是可能的还是我应该使用其他一些制作循环的方法。我尝试制作一个for(;;){},但这会导致错误并且网页永远不会加载。这是我目前的代码。



var red = document.getElementById("circleRed");
var orange = document.getElementById('circleOrange')
var green = document.getElementById('circleGreens');
    
setInterval(
    
  setTimeout( function(){
    red.style.backgroundColor = "red";
  }, 2000),
    
   setTimeout(function(){
      green.style.backgroundColor = "green";
      red.style.backgroundColor = "black";
   }, 5000),
    
    setTimeout(function(){
      orange.style.backgroundColor = "orange";
      green.style.backgroundColor = "black";
    }, 10000),
    
    5000);

#circleRed, #circleGreens, #circleOrange {
    width: 50px;
    height: 50px;
    -webkit-border-radius: 25px;
    -moz-border-radius: 25px;
    border-radius: 25px;
    margin-bottom: 10px;
    background-color: "black";
}

.back {
    width: 60px;
    margin: 10px 0px 10px 20px;
    padding-left: 10px;
    padding-top: 10px;
    padding-bottom: 10px;
    background-color: black;
}
    
body{
    margin: 0;
}

<div class="back">
  <div id="circleRed">
  </div>
  <div id="circleOrange">
  </div>
  <div id="circleGreens">
  </div>
</div>
&#13;
&#13;
&#13;

5 个答案:

答案 0 :(得分:1)

setInterval,就像setTimeout一样,还需要一个函数作为第一个参数传递,在那个函数中你就可以组成你的setTimeout了。

var red = document.getElementById("circleRed");
var orange = document.getElementById('circleOrange');
var green = document.getElementById('circleGreens');

setInterval(function () {
  red.style.backgroundColor = "black";
  orange.style.backgroundColor = "black";
  green.style.backgroundColor = "black";

  setTimeout(function () {
    red.style.backgroundColor = "red";
  }, 2000);

  setTimeout(function () {
    green.style.backgroundColor = "green";
    red.style.backgroundColor = "black";
  }, 5000);

  setTimeout(function () {
    orange.style.backgroundColor = "orange";
    green.style.backgroundColor = "black";
  }, 8000);
}, 10000)

我已经调整了你的时间,因为你的最终超时时间长于间隔时间。你可以在这里看到这个:codepen example

答案 1 :(得分:1)

您可以在setTimeout函数中调整所有loop函数。并使用setInterval调用此循环函数。 注意:我还更改了代码中的一些颜色更改部分。

jsfiddle链接:https://jsfiddle.net/zgdx5xan/

var red = document.getElementById("circleRed");
var orange = document.getElementById('circleOrange')
var green = document.getElementById('circleGreens');

loop();
setInterval(loop,11000);

function loop(){
	console.log("loop started")
  setTimeout( function(){
    red.style.backgroundColor = "red";
    orange.style.backgroundColor = "black";
    green.style.backgroundColor = "black";
    console.log("red opened")
  }, 2000);

   setTimeout(function(){
    green.style.backgroundColor = "green";
    red.style.backgroundColor = "black";
    console.log("green opened")
  }, 5000);

  setTimeout(function(){
    orange.style.backgroundColor = "orange";
    green.style.backgroundColor = "black";
    red.style.backgroundColor = "black";
    console.log("orange opened")    
  }, 10000);
}
#circleRed, #circleGreens, #circleOrange {
  width: 50px;
  height: 50px;
  -webkit-border-radius: 25px;
  -moz-border-radius: 25px;
  border-radius: 25px;
  margin-bottom: 10px;
  background-color: "black";
}



.back{
  width: 60px;
  margin: 10px 0px 10px 20px;
  padding-left: 10px;
  padding-top: 10px;
  padding-bottom: 10px;
  background-color: black;
}

body{
  margin: 0;
}
 
   <div class="back">
    <div id="circleRed">

    </div>
    <div id="circleOrange">

    </div>
    <div id="circleGreens">

    </div>
  </div>
 

答案 2 :(得分:1)

将交通信号灯视为具有3种状态的对象,redOn,greenOn和OrangeOn。您需要遍历状态,因此从redOn开始传递序列中的下一个并重置最后一个。我认为这里不需要setInterval,因为它会让你关心那些不相关的总时间。

&#13;
&#13;
var red = document.getElementById("circleRed");
var orange = document.getElementById('circleOrange')
var green = document.getElementById('circleGreens');

var redFor = 200 //2000
var greenFor = 500 //5000
var orangeFor = 1000 //10000

let redOn = function(next) {
  red.style.backgroundColor = "red";
  orange.style.backgroundColor = "black";
  setTimeout(next, redFor);
}

let orangeOn = function(next) {
  orange.style.backgroundColor = "orange";
  green.style.backgroundColor = "black";
  setTimeout(next, orangeFor);
}

let greenOn = function(next) {
  green.style.backgroundColor = "green";
  red.style.backgroundColor = "black";
  setTimeout(next, greenFor);
}

let start = function() {
  redOn(function() {
    greenOn(function() {
      orangeOn(start)
    })
  })
}

start()
&#13;
#circleRed,
#circleGreens,
#circleOrange {
  width: 50px;
  height: 50px;
  -webkit-border-radius: 25px;
  -moz-border-radius: 25px;
  border-radius: 25px;
  margin-bottom: 10px;
  background-color: "black";
}

.back {
  width: 60px;
  margin: 10px 0px 10px 20px;
  padding-left: 10px;
  padding-top: 10px;
  padding-bottom: 10px;
  background-color: black;
}

body {
  margin: 0;
}
&#13;
<html>

<head>
  <link rel="stylesheet" type="text/css" href="object2.css">
  <meta charset="utf-8">
  <title></title>
</head>

<body>
  <div class="back">
    <div id="circleRed"></div>
    <div id="circleOrange"></div>
    <div id="circleGreens"></div>
  </div>
  <script src="objects1.js"></script>
</body>

</html>
&#13;
&#13;
&#13;

答案 3 :(得分:1)

这是一个替代实现,每个灯都有相同的时间。

&#13;
&#13;
var red    = document.getElementById('circleRed');
var orange = document.getElementById('circleOrange');
var green  = document.getElementById('circleGreens');

/* Set an array with the desired order to turn on lights */
var lights = [red, green, orange];

function open(light) {
    light.classList.add('opened');
}

function close(light) {
    light.classList.remove('opened');
}


function change() {
    close(lights[i]);
    i = (i + 1) % lights.length;
    open(lights[i]);
}

/* Start */
var i = 0;
open(lights[i]);
setInterval(change, 1000);
&#13;
.circle {
    width: 50px;
    height: 50px;
    border-radius: 25px;
    margin: 5px;
    opacity: 0.2;
    transition: opacity 200ms;
}

.circle.opened {
    opacity: 1;
}

#circleRed {
    background-color: red;
}

#circleOrange {
    background-color: orange;
}

#circleGreens {
    background-color: green;
}


.back {
    width: 60px;
    padding: 5px;
    background-color: black;
}
&#13;
<div class="back">
  <div id="circleRed" class="circle"></div>
  <div id="circleOrange" class="circle"></div>
  <div id="circleGreens" class="circle"></div>
</div>
&#13;
&#13;
&#13;

<强>解释

不是将每个圆圈的背景颜色从黑色更改为自己的颜色以点亮圆圈,反之亦然关闭,在我的示例中,所有圆圈各自的颜色(红色,绿色或橙色)逐渐消失(几乎)透明与opacity: 0.2(最初我使用0,但我觉得0.2看起来更好)参见:opacity

因此,类.circle的所有元素都有:

.circle {
    /* Other properties */
    opacity: 0.2;
}

然后,我使用一个名为opened的类将不透明度变为1,使圆圈可见。

.circle.opened {
    opacity: 1;
}

由于.circle.opened的{​​{3}}高于.circle,因此不透明度:1对具有这两个类(circleopened)的元素有优势。

要从灯光项目中添加或删除班级opened,我会使用两个操作元素specificity的简单函数openclose这很重要。一般来说,建议在类中定义元素的属性(样式),并使用JS添加或删除这些类来改变直接用JS修改元素样式的元素。

所以,它更干净,更值得推荐:

/* CSS */
.red { background-color: red }

/* Javascript */
var element = document.getElementById('#element_ID');
element.classList.add('red');

比:

/* Javascript */
var element = document.getElementById('#element_ID');
element.style.backgroundColor = 'red';

尽管第二种方式看起来似乎更容易。

为了改变灯光,我按照所需的顺序制作了一个包含元素的数组:

var lights = [red, green, orange];

正如您所看到的,灯光classList中的每个元素都是圆圈之一,我们已经将document.getElementById()存储在变量中(如果您不熟悉数组,请花一些时间阅读和理解它们是什么以及它们是如何工作的。它们是任何编程语言中最基本的数据结构之一,因此掌握它们非常重要。)

首先,我发起一个全局变量0var i = 0),然后点亮第一个灯光:

open(lights[i]);

由于i等于0,lights[i],所以lights[0]red(在JS中,与大多数语言一样,数组从0开始计算其元素)。这样,open(lights[i])open(red)相同。

然后我做了一个setInterval(change, 1000)所以每隔一秒调用一次函数change()。这个change函数做了什么?

基本上:

// Turn off the current light
close(lights[i]);

// Increment i, so that lights[i] points to the next element... 
i = (i + 1) % lights.length;

// Turn on this next element
open(lights[i]);

这里最罕见的事情可能是增量。为什么我i = (i + 1) % lights.length而不仅仅是i++

如果我在连续拨打i++change ilights[i]将会是:0,1,2,3,4,5,6 ......所以,当我尝试访问lights我会收到错误,因为i++; if (i > 2) { i = 0; } 数组的第3,4,5 ...位置没有元素。

我需要我的序列:0,1,2,0,1,2,0,1,2 ......

如何获得所需的序列而不是0,1,2,3,4,5,6 ......?

也许更容易理解的方式是:

%

但我使用Array运算符(var lights = { red: { node: document.getElementById('circleRed'), duration: 4000, }, green: { node: document.getElementById('circleGreens'), duration: 2000, }, orange: { node: document.getElementById('circleOrange'), duration: 800, } }; var order = ['red', 'green', 'orange']; function open(light) { light.node.classList.add('opened'); } function close(light) { light.node.classList.remove('opened'); } function change() { close(lights[order[i]]); i = (i + 1) % order.length; open(lights[order[i]]); setTimeout(change, lights[order[i]].duration); } /* Start */ var i = 0; open(lights[order[i]]); setTimeout(change, lights[order[i]].duration);)来达到同样的效果。

我希望这有帮助!

另一个可以轻松配置每个灯光的持续时间:

&#13;
&#13;
.circle {
    width: 50px;
    height: 50px;
    border-radius: 25px;
    margin: 5px;
    opacity: 0;
    transition: opacity 200ms;
}

.circle.opened {
    opacity: 1;
}

#circleRed {
    background-color: red;
}

#circleOrange {
    background-color: orange;
}

#circleGreens {
    background-color: green;
}


.back {
    width: 60px;
    padding: 5px;
    background-color: black;
}
&#13;
<div class="back">
  <div id="circleRed" class="circle"></div>
  <div id="circleOrange" class="circle"></div>
  <div id="circleGreens" class="circle"></div>
</div>
&#13;
fileBytes = Encoding.UTF8.GetBytes(fileStream.ReadToEnd()); 
&#13;
&#13;
&#13;

答案 4 :(得分:0)

将所有setTimeout( function(){})放在一个函数中,然后就可以了

  

注意:要使setInterval正常工作,毫秒必须至少是setTimeout个函数的总和。

orange出现时,您也忘记将red设置为黑色。

&#13;
&#13;
var red = document.getElementById("circleRed");
var orange = document.getElementById('circleOrange')
var green = document.getElementById('circleGreens');
    
setInterval(function(){ myTimer() }, 17000);
    function myTimer() {
  setTimeout( function(){
    red.style.backgroundColor = "red";
    orange.style.backgroundColor = "black";
  }, 2000),
    
   setTimeout(function(){
      green.style.backgroundColor = "green";
      red.style.backgroundColor = "black";
   }, 5000),
    
    setTimeout(function(){
      orange.style.backgroundColor = "orange";
      green.style.backgroundColor = "black";
    }, 10000)
    }
    myTimer();
&#13;
#circleRed, #circleGreens, #circleOrange {
    width: 50px;
    height: 50px;
    -webkit-border-radius: 25px;
    -moz-border-radius: 25px;
    border-radius: 25px;
    margin-bottom: 10px;
    background-color: "black";
}

.back {
    width: 60px;
    margin: 10px 0px 10px 20px;
    padding-left: 10px;
    padding-top: 10px;
    padding-bottom: 10px;
    background-color: black;
}
    
body{
    margin: 0;
}
&#13;
<div class="back">
  <div id="circleRed">
  </div>
  <div id="circleOrange">
  </div>
  <div id="circleGreens">
  </div>
</div>
&#13;
&#13;
&#13;