Javascript 试图让两个交通灯按顺序工作
我有一个应用程序,我已经写了,增加了一组交通灯在屏幕上按下一个按钮。交通灯在10秒后自动循环从红色变为黄色,然后在2秒后变为绿色,然后在10秒后变回黄色,最后变回红色。我想在屏幕上添加几个交通灯,并让它们同时运行,但当我添加第二个交通灯时,第一个交通灯的序列将冻结在其达到的任何状态。关于如何让它继续运行,从而在同一时间有多个光循环通过序列,有什么想法吗 转换由javascript通过状态机控制 有人对如何使这项工作顺利进行有什么想法吗 谢谢 抢劫 英国伦敦Javascript 试图让两个交通灯按顺序工作,javascript,html,state-machine,Javascript,Html,State Machine,我有一个应用程序,我已经写了,增加了一组交通灯在屏幕上按下一个按钮。交通灯在10秒后自动循环从红色变为黄色,然后在2秒后变为绿色,然后在10秒后变回黄色,最后变回红色。我想在屏幕上添加几个交通灯,并让它们同时运行,但当我添加第二个交通灯时,第一个交通灯的序列将冻结在其达到的任何状态。关于如何让它继续运行,从而在同一时间有多个光循环通过序列,有什么想法吗 转换由javascript通过状态机控制 有人对如何使这项工作顺利进行有什么想法吗 谢谢 抢劫 英国伦敦 var i=1; var交通灯=功能
var i=1;
var交通灯=功能(i){
var计数=0;
var light_container=document.getElementById('light-container-'+i);
var currentState=新红色(此灯为容器);
this.change=函数(状态){
当前状态=状态;
currentState.go();
}
this.start=函数(){
currentState.go();
}
}
var Red=功能(灯、灯和容器){
这个。光=光;
this.go=函数(){
light#container.querySelector(“#内圈红色”).style.backgroundColor=“#d8412c”;
控制台日志(轻型容器);
setTimeout(函数(){
灯。更换(新黄色(灯“红色”、灯(集装箱))
}, 10000);
}
}
变量黄=功能(灯光、原点、灯光容器){
这个。光=光;
this.go=函数(){
light#container.querySelector(“#内圈黄色”).style.backgroundColor=“#fad201”;
setTimeout(函数(){
如果(原点==“红色”){
灯。改变(新的绿色(灯,灯)容器);
light#container.querySelector(“#内圈红色”).style.backgroundColor=“#111111”;
light#container.querySelector(“#内圈黄色”).style.backgroundColor=“#111111”;
}else if(原点==“绿色”){
灯。改变(新的红色(灯,灯)容器);
light#container.querySelector(“#内圈黄色”).style.backgroundColor=“#111111”;
}
}, 2000);
}
}
绿色变量=功能(灯、灯和容器){
这个。光=光;
this.go=函数(){
light#container.querySelector(“#内圈绿色”).style.backgroundColor=“#33A532”;
setTimeout(函数(){
灯。更换(新黄色(灯、‘绿色’、灯和容器))
light#container.querySelector(“#内圆绿色”).style.backgroundColor=“#111111”;
}, 10000);
}
};
函数运行(){
document.getElementById(“容器”).innerHTML+='';
var灯=新交通灯(i);
light.start();
i++;
}
。外圆红色,
.外圆黄色,
.外圆绿色{
背景色:#6969;
边框:2件纯黑;
宽度:50px;
高度:40px;
边界半径:15px;
显示:表格;
}
#轻容器-1,
#轻容器-2,
#轻型集装箱-3{
边缘顶部:20px;
浮动:左;
左边距:70像素;
}
#内圆红色,
#内圈黄色,
#内圆绿色{
宽度:20px;
高度:20px;
边界半径:25px;
边框:2px实心#111111;
保证金:0自动;
利润上限:7.5px;
背景色:#111111;
}
#钮扣{
宽度:200px;
高度:20px;
填充:10px;
背景颜色:蓝色;
颜色:#ffffff;
光标:指针;
}
+添加新的交通灯
我想这是因为您没有使用唯一的ID。下面是代码中的一个示例
light\u container.querySelector(“#内圈红色”).style.backgroundColor
如果页面上有多个#内圆红色
,您将看到如下错误。也许你可以试着对你的选择器更具体一些——像这样
#light-container-1 .inner-circle-red
#light-container-2 .inner-circle-red
我还添加了几个变量和一个循环来帮助管理多个灯光
for(let i = 1; i <= lights; i++){
var light = new TrafficLight(i);
light.start();
}
+添加新的交通灯
一个问题是,正如Lewis已经指出的,您有多个元素具有相同的id
。JavaScript只能处理其中之一
另一个问题是使用innerHTML
删除#container
的内容。存储在交通灯
、红色
、黄色
和绿色
类中的引用随后被销毁。这家商店运转正常,但看不出来是这样的。改用DOM操作
var light_container = document.createElement('div');
light_container.id = "light-container-" + i;
light_container.innerHTML = '<div class="outer-circle-red"><div class="inner-circle-red"></div></div><div class="outer-circle-yellow"><div class="inner-circle-yellow"></div></div><div class="outer-circle-green"><div class="inner-circle-green"></div></div>';
document.getElementById("container").appendChild(light_container);
+添加新的交通灯
谢谢你的回答。作为一个额外的功能,我添加了一个控件,允许用户单独启动每个交通灯。我试图找出如何使用户能够永久停止每个交通灯,而不会停止所有其他交通灯
这是我迄今为止更新的代码-注意在var Red中添加了'this.stop()'函数。我希望代码停止那里的旋转,而不是继续黄色和绿色
谢谢
抢劫
交通灯
#钮扣{
宽度:200px;
高度:20px;
填充:10px;
背景颜色:蓝色;
颜色:#ffffff;
光标:指针;
}
.按钮{
宽度:15px;
高度:20px;
填充:10px;
背景色:红色;
颜色:#ffffff;
光标:指针;
保证金:20px自动;
文本对齐:居中;
文本转换:大写;
字体大小:粗体;
}
.外圈红色、.外圈黄色、.外圈绿色{
背景色:#6969;
保证金:0自动;
边框:2件纯黑;
宽度:50px;
高度:40px;
边界半径:15px;
显示:表格;
}
.轻型集装箱{
利润率:20px 30px 0 30px;
利润上限:20px
<!DOCTYPE html>
<html>
<head>
<title>Traffic Lights</title>
<style type="text/css">
#button {
width: 200px;
height: 20px;
padding: 10px;
background-color: blue;
color: #ffffff;
cursor: pointer;
}
.button {
width: 15px;
height: 20px;
padding: 10px;
background-color: red;
color: #ffffff;
cursor: pointer;
margin: 20px auto;
text-align: center;
text-transform: uppercase;
font-weight: bold;
}
.outer-circle-red, .outer-circle-yellow, .outer-circle-green {
background-color: #696969;
margin: 0 auto;
border: 2px solid black;
width: 50px;
height: 40px;
border-radius: 15px;
display: table;
}
.light-container {
margin: 20px 30px 0 30px;
margin-top: 20px;
float: left;
}
.inner-circle-red, .inner-circle-yellow, .inner-circle-green {
width: 20px;
height: 20px;
border-radius: 25px;
border: 2px solid #111111;
margin: 0 auto;
margin-top: 7.5px;
background-color: #111111;
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
margin-top: 20px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
</style>
</head>
<body>
<div id="button" onclick="initiate()">+ Add a new traffic light</div>
<div id="container">
</div>
<script type="text/javascript">
var i = 1;
var TrafficLight = function (i) {
var count = 0;
var light_container = document.getElementById('light-container-' + i);
var currentState = new Red(this, light_container);
this.change = function (state) {
currentState = state;
currentState.go();
}
this.start = function () {
currentState.go();
}
this.stop = function () {
currentState.stop();
}
}
var Red = function (light, light_container) {
this.light = light;
this.go = function () {
light_container.querySelector('.inner-circle-red').style.backgroundColor = '#d8412c';
console.log(light_container);
setTimeout(function(){
light.change(new Yellow(light, 'red', light_container))
}, 12000);
}
this.stop = function () {
light_container.querySelector('.inner-circle-red').style.backgroundColor = '#111111';
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#111111';
light_container.querySelector('.inner-circle-green').style.backgroundColor = '#111111';
// Switch all the lights off.
return;
}
}
var Yellow = function (light, origin, light_container) {
this.light = light;
this.go = function () {
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#fad201';
setTimeout(function(){
if(origin == 'red'){
light.change(new Green(light, light_container));
light_container.querySelector('.inner-circle-red').style.backgroundColor = '#111111';
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#111111';
} else if(origin == 'green'){
light.change(new Red(light, light_container));
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#111111';
}
}, 2000);
}
}
var Green = function (light, light_container) {
this.light = light;
console.log('here');
this.go = function () {
light_container.querySelector('.inner-circle-green').style.backgroundColor = '#33A532';
setTimeout(function(){
light.change(new Yellow(light, 'green', light_container))
light_container.querySelector('.inner-circle-green').style.backgroundColor = '#111111';
}, 14000);
}
};
function initiate(){
var light_container = document.createElement('div');
light_container.id = "light-container-" + i;
light_container.className = "light-container";
light_container.innerHTML = '<div class="outer-circle-red"><div class="inner-circle-red"></div></div><div class="outer-circle-yellow"><div class="inner-circle-yellow"></div></div><div class="outer-circle-green"><div class="inner-circle-green"></div></div><label class="switch"><input type="checkbox" class="off" onclick="toggleRun(this, ' + i + ');"><span class="slider round"></span></label>';
document.getElementById("container").appendChild(light_container);
i++;
}
function toggleRun(item, i){
if(item.className == "off"){
item.className="on";
run(i);
} else {
item.className="off";
stop(i);
}
}
function run(i){
var light = new TrafficLight(i);
light.start();
}
function stop(i){
var light = new TrafficLight(i);
light.stop();
}
function exit( status ){
var i;
if (typeof status === 'string') {
alert(status);
}
window.addEventListener('error', function (e) {e.preventDefault();e.stopPropagation();}, false);
var handlers = [
'copy', 'cut', 'paste',
'beforeunload', 'blur', 'change', 'click', 'contextmenu', 'dblclick', 'focus', 'keydown', 'keypress', 'keyup', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'resize', 'scroll',
'DOMNodeInserted', 'DOMNodeRemoved', 'DOMNodeRemovedFromDocument', 'DOMNodeInsertedIntoDocument', 'DOMAttrModified', 'DOMCharacterDataModified', 'DOMElementNameChanged', 'DOMAttributeNameChanged', 'DOMActivate', 'DOMFocusIn', 'DOMFocusOut', 'online', 'offline', 'textInput',
'abort', 'close', 'dragdrop', 'load', 'paint', 'reset', 'select', 'submit', 'unload'
];
function stopPropagation (e) {
e.stopPropagation();
// e.preventDefault(); // Stop for the form controls, etc., too?
}
for (i=0; i < handlers.length; i++) {
window.addEventListener(handlers[i], function (e) {stopPropagation(e);}, true);
}
if (window.stop) {
window.stop();
}
throw '';
}
</script>
</body>
</html>```