Остановка конечного автомата - PullRequest
0 голосов
/ 14 июня 2019

У меня есть приложение, которое я написал, который добавляет светофор на экране после нажатия кнопки. Через 10 секунд светофор автоматически переключается с красного на желтый, затем через две секунды на зеленый, затем через 10 секунд на желтый и, наконец, на красный. Я добавил элемент управления, который позволяет пользователю запускать каждый светофор отдельно. Я пытаюсь выяснить, как разрешить пользователю постоянно останавливать каждый светофор без остановки всех остальных.

Вот мой обновленный код - обратите внимание на добавление функции this.stop () внутри var Red. Я бы хотел, чтобы код остановил вращение, а не продолжал желтеть и зеленеть.

Спасибо

Rob

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 '';
}
#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%;
}
<div id="button" onclick="initiate()">+ Add a new traffic light</div>

<div id="container">

</div>

1 Ответ

0 голосов
/ 14 июня 2019

Решением этой проблемы является сохранение идентификатора, возвращенного var id = setTimeout(), так что вы можете использовать clearTimeout( id ); позже, чтобы полностью остановить повторный запуск функции тайм-аута.

Так что-то вроде: this.timeout = setInterval(function(){ /* insert the color changing code */ }, 10000 );.

Если вы выберете такое решение, было бы удобно поместить код тайм-аута в один тайм-аут, а не иметь отдельный класс для каждого цвета.Но вы всегда можете использовать массив для хранения всех тайм-аутов и зациклить его, чтобы отменить, если вам нужны разные таймауты для каждого цвета.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...