我有一个已经编写的应用程序,可以在按下按钮时在屏幕上添加一组交通信号灯。交通灯会在10秒钟后自动从红色变为黄色,然后在两秒钟后变为绿色,然后在10秒钟后恢复为黄色,最后变为红色。我想将其中几个红绿灯添加到屏幕上并使其同时运行,但是当我添加第二个红绿灯时,第一个红绿灯的序列会冻结在其达到的任何状态。关于如何使其继续运行的任何想法-从而使多个光亮同时循环?

过渡由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();
  }

}

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))
    }, 10000);
  }
}

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;

  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';
    }, 10000);
  }
};


function run() {

  document.getElementById("container").innerHTML += '<div id="light-container-' + i + '"><div class="outer-circle-red"><div id="inner-circle-red"></div></div><div class="outer-circle-yellow"><div id="inner-circle-yellow"></div></div><div class="outer-circle-green"><div id="inner-circle-green"></div></div></div>';

  var light = new TrafficLight(i);

  light.start();
  i++;
}

.outer-circle-red,
.outer-circle-yellow,
.outer-circle-green {
  background-color: #696969;
  border: 2px solid black;
  width: 50px;
  height: 40px;
  border-radius: 15px;
  display: table;
}

#light-container-1,
#light-container-2,
#light-container-3 {
  margin-top: 20px;
  float: left;
  margin-left: 70px;
}

#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;
}

#button {
  width: 200px;
  height: 20px;
  padding: 10px;
  background-color: blue;
  color: #ffffff;
  cursor: pointer;
}

<div id="button" onclick="run()">+ Add a new traffic light</div>

<div id="container">

</div>

最佳答案

一个问题是,正如Lewis已经说过的那样,您有多个具有相同id的元素。 JavaScript只能处理其中之一。

另一个问题是您使用#container删除innerHTML的内容。存储在TrafficLightRedYellowGreen类中的引用将被销毁。该商店可以正常运行,但是看不到它。请改用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 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();
  }

}

var Red = function(light, light_container) {
  this.light = light;

  this.go = function() {
    light_container.querySelector('.inner-circle-red').style.backgroundColor = '#d8412c';

    setTimeout(function() {
      light.change(new Yellow(light, 'red', light_container))
    }, 10000);
  }
}

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;

  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';
    }, 10000);
  }
};


function run() {
  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 light = new TrafficLight(i);

  light.start();
  i++;
}

.outer-circle-red,
.outer-circle-yellow,
.outer-circle-green {
  background-color: #696969;
  border: 2px solid black;
  width: 50px;
  height: 40px;
  border-radius: 15px;
  display: table;
}
[id^=light-container] {
  margin-top: 20px;
  float: left;
  margin-left: 70px;
}

.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;
}

#button {
  width: 200px;
  height: 20px;
  padding: 10px;
  background-color: blue;
  color: #ffffff;
  cursor: pointer;
}

<div id="button" onclick="run()">+ Add a new traffic light</div>

<div id="container">

</div>

09-27 19:21