Javascript таймер обратного отсчета - PullRequest
1 голос
/ 13 апреля 2020

У меня есть таймер на 1:30 в JS, который относится к викторине. В тесте, если пользователь выбирает неправильный ответ, таймер вычитается на 10 секунд. Эта часть работает. Однако, когда таймер достигает 1:00, он перезапускается до 1:59 секунд и никогда не опускается ниже 1 минуты.

function startTimer() {
  var p_time = document.getElementById('time').innerHTML;
  var timeArray = p_time.split(/[:]+/);
  var min = timeArray[0];
  var sec = checkSecond((timeArray[1] - 1));
  if (sec === 59) {
    min = min - 1
  }

  document.getElementById('time').innerHTML = min + ":" + sec;

  if (min <= 0 && sec == 0) {
    clearTimeout(timerRef)
    alert("Time is up!")
    return;
  }

  if(min === 1 && sec === 0) {
    min = 0;
  }
  setTimeout(startTimer, 1000);
}

function checkSecond(seconds) {
  if (seconds < 10 && seconds >= 0) {
    seconds = "0" + seconds
  };
  if (seconds < 0) {
    seconds = "59"
  };
  return seconds;
}

function wrongTimer () {
  var x_time = document.getElementById('time').innerHTML;
  var wrongArray = x_time.split(/[:]+/);
  var x_min = wrongArray[0];
  var x_sec = checkSecond((wrongArray[1]-1));
  if(x_sec === 59) {
    x_min = x_min - 1
  }
  x_sec -= 10;
  console.log(document.getElementById('time').innerHTML);
  console.log("sec " + x_sec);
  document.getElementById('time').innerHTML = x_min + ":" + x_sec;
}

Позже я вызываю функцию falseTimer в моем коде (не показан). Как заставить таймер продолжать обратный отсчет даже после возможных вычетов?

JS Викторина

Ответы [ 3 ]

2 голосов
/ 13 апреля 2020

Проблема в (sec === 59), вы проверяете, является ли sec 59 (Число), но sec равно "59" (Строка).

Вы можете проанализировать строку на номер, просто проверьте, является ли sec строка "59".

Я только что сделал последнее в приведенном ниже примере, рабочий фрагмент:

function startTimer() {
  var p_time = document.getElementById("time").innerHTML;
  var timeArray = p_time.split(/[:]+/);
  var min = timeArray[0];
  var sec = checkSecond(timeArray[1] - 1);
  if (sec === "59") { // <- the fix
    min = min - 1;
  }

  document.getElementById("time").innerHTML = min + ":" + sec;

  if (min <= 0 && sec == 0) {
    clearTimeout(timerRef);
    alert("Time is up!");
    return;
  }

  if (min === 1 && sec === 0) {
    min = 0;
  }
  var timerRef = setTimeout(startTimer, 1000);
}

function checkSecond(seconds) {
  if (seconds < 10 && seconds >= 0) {
    seconds = "0" + seconds;
  }
  if (seconds < 0) {
    seconds = "59";
  }
  return seconds;
}

function wrongTimer() {
  var x_time = document.getElementById("time").innerHTML;
  var wrongArray = x_time.split(/[:]+/);
  var x_min = wrongArray[0];
  var x_sec = checkSecond(wrongArray[1] - 1);
  if (x_sec === 59) {
    x_min = x_min - 1;
  }
  x_sec -= 10;
  console.log(document.getElementById("time").innerHTML);
  console.log("sec " + x_sec);
  document.getElementById("time").innerHTML = x_min + ":" + x_sec;
}

startTimer();
<div id="time">1:05</div>
1 голос
/ 13 апреля 2020

Вы используете операторы строгого сравнения === для сравнений, которые возвращают true, только если два элемента имеют одинаковое значение и имеют одинаковый тип. Проблема в том, что ваша переменная секунд является строкой, поэтому сравнение с целочисленными значениями будет возвращать false независимо от значения.

Я применил несколько других исправлений и удалил некоторый ненужный код, проверьте ниже:

function startTimer() {
  var p_time = document.getElementById('time').innerHTML;
  var timeArray = p_time.split(":");
  var min = timeArray[0];
  var sec = checkSecond((timeArray[1] - 1));
  if (sec == 59) {
    min = min - 1
  }

  if (min < 0) {
    clearTimeout(timerRef)
    alert("Time is up!")
    return;
  }

  document.getElementById('time').innerHTML = min + ":" + sec;
  
  var timerRef = setTimeout(startTimer, 1000);
}

function checkSecond(seconds) {
  if (seconds < 10 && seconds >= 0) {
    seconds = "0" + seconds
  };
  if (seconds < 0) {
    seconds = "59"
  };
  return seconds;
}

function wrongTimer () {
  var x_time = document.getElementById('time').innerHTML;
  var wrongArray = x_time.split(/[:]+/);
  var x_min = wrongArray[0];
  var x_sec = checkSecond((wrongArray[1]-1));
  if(x_sec === 59) {
    x_min = x_min - 1
  }
  x_sec -= 10;
  console.log(document.getElementById('time').innerHTML);
  console.log("sec " + x_sec);
  document.getElementById('time').innerHTML = x_min + ":" + x_sec;
}

startTimer();
<div id="time">1:10</div>
0 голосов
/ 13 апреля 2020

Для вас может быть лучше выполнить рефакторинг вашего кода, чтобы в памяти был счетчик, отслеживающий, сколько секунд должен иметь таймер (ie 120, когда он начинается через 2 минуты, затем до 60, когда он идет до 1 минуты). Эту настройку будет проще кодировать в UX-дружественный таймер (MM: SS), поскольку вы будете всегда конвертировать в одну сторону, и любые добавления или вычеты в этот код будут просто вноситься в этот счетчик и затем переходить к вашим преобразованиям в пользовательский интерфейс.

В нынешнем виде вы находите время, оставшееся внутри вашего HTML, вычитаете временные единицы (считая секунды и минуты), а затем выполняете все свои выводы. Это требует больше вычислений, чем действительно необходимо. Это также делает реальную боль до go с 1:00 до 0: 59.

Тем не менее, вы должны быть предупреждены, что если вы отслеживаете эту переменную счетчика на стороне клиента, это может быть манипулировать кем-то умным, чтобы дать им больше времени, чем предполагалось. Вы должны быть осторожны, как вы гарантируете целостность таймера, будь то в этом решении или в другом.

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