我刚开始学习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;
答案 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,因为它会让你关心那些不相关的总时间。
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;
答案 3 :(得分:1)
这是一个替代实现,每个灯都有相同的时间。
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;
<强>解释强>
不是将每个圆圈的背景颜色从黑色更改为自己的颜色以点亮圆圈,反之亦然关闭,在我的示例中,所有圆圈各自的颜色(红色,绿色或橙色)逐渐消失(几乎)透明与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对具有这两个类(circle
和opened
)的元素有优势。
要从灯光项目中添加或删除班级opened
,我会使用两个操作元素specificity的简单函数open
和close
。 这很重要。一般来说,建议在类中定义元素的属性(样式),并使用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()
存储在变量中(如果您不熟悉数组,请花一些时间阅读和理解它们是什么以及它们是如何工作的。它们是任何编程语言中最基本的数据结构之一,因此掌握它们非常重要。)
首先,我发起一个全局变量0
(var 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
i
,lights[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);
)来达到同样的效果。
我希望这有帮助!
另一个可以轻松配置每个灯光的持续时间:
.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;
答案 4 :(得分:0)
将所有setTimeout( function(){})
放在一个函数中,然后就可以了
注意:要使
setInterval
正常工作,毫秒必须至少是setTimeout
个函数的总和。
当orange
出现时,您也忘记将red
设置为黑色。
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;