Мои часы таймера JS не останавливаются при двойном нажатии на кнопку запуска

У меня есть простая логика секундомера HTML, где я могу запускать и останавливать часы нажатием кнопки. Нажав на кнопку start, можно запустить таймер (показывает текущее время) и обновлять его каждую секунду. Его можно остановить, нажав кнопку stop. Но если дважды нажать кнопку start, я ничего не смогу сделать, чтобы остановить таймер. Ниже мой код:

var hour = document.getElementById("hoursOut");
  var minute = document.getElementById("minsOut");
  var second = document.getElementById("secsOut");
  var btnStart = document.getElementById("btnStart");
  var btnStop = document.getElementById("btnStop");

  var waitTimer;

  function displayTime() {
    var currentTime = new Date();
    var currentHour = currentTime.getHours();
    var currentMinute = currentTime.getMinutes();
    var currentSeconds = currentTime.getSeconds();

    hour.innerHTML = twoDigit(currentHour) + ":";
    minute.innerHTML = twoDigit(currentMinute) + ":";
    second.innerHTML = twoDigit(currentSeconds);
  }

  function twoDigit(digit) {
    if (digit < 10) {
      digit = "0" + digit;
    }
    return digit;
  }

function startClock() {
    waitTimer = setInterval(displayTime, 1000);
  }

  function stopClock() {
    clearInterval(waitTimer);
  }

  btnStart.onclick = startClock;
  btnStop.onclick = stopClock;
    <h1>JavaScript Clock</h1>

    <div id = "calendarBox">
      <!-- OUTPUT TIME VALUES -->
      <p class = "timeDisplay">
        <span id = "hoursOut">00:</span>
        <span id = "minsOut">00:</span>
        <span id = "secsOut">00</span>
      </p>

      <!-- BUTTON SET -->
      <input id = "btnStart" type = "button" value = "START" />
      <input id = "btnStop" type = "button" value = "STOP" />
    </div>

Я проверил некоторые ответы в stackoverflow, но в большинстве решений используется for-loop от 0 до 1000, пока он не найдет идентификатор интервала и не остановит все их с помощью цикла. Я уверен, что должно быть элегантное решение, чем это.

// some stackoverflow suggested answer
    for (var i = 1; i < 99999; i++)
         window.clearInterval(i);

Вам нужно очистить интервал (если он существует), прежде чем установить его снова

Yoshie2000 18.03.2022 22:36

Просто добавьте какой-нибудь флаг, например, isStarted=false и измените его при первом запуске. Затем добавьте if (isStarted) в вашу функцию запуска

Ludvík Prokopec 18.03.2022 22:40

Вызов setInterval возвращает целочисленный идентификатор интервала, который вы можете передать clearInterval(id) позже. setInterval(displayTime, 1000); в корне неверно. См. Таймер обратного отсчета JavaScript с нажатием клавиши для сброса таймера.

ggorlen 18.03.2022 22:45
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

когда вы дважды щелкаете, вы запускаете новый setInterval(). Итак, теперь у вас есть два заданных интервала. Единственная проблема в том, что вы не можете получить доступ к первому, потому что вы назвали второе таким же именем. Проверьте, существует ли waitTimer и останавливает ли он его. см. код:

ОБНОВЛЕНИЕ: на самом деле вам даже не нужен оператор if. просто вызовите stopClock() перед тем, как установить waitTimer -- исправлен фрагмент кода

var hour = document.getElementById("hoursOut");
  var minute = document.getElementById("minsOut");
  var second = document.getElementById("secsOut");
  var btnStart = document.getElementById("btnStart");
  var btnStop = document.getElementById("btnStop");

  var waitTimer;

  function displayTime() {
    var currentTime = new Date();
    var currentHour = currentTime.getHours();
    var currentMinute = currentTime.getMinutes();
    var currentSeconds = currentTime.getSeconds();

    hour.innerHTML = twoDigit(currentHour) + ":";
    minute.innerHTML = twoDigit(currentMinute) + ":";
    second.innerHTML = twoDigit(currentSeconds);
  }

  function twoDigit(digit) {
    if (digit < 10) {
      digit = "0" + digit;
    }
    return digit;
  }

function startClock() {
    stopClock();
    waitTimer = setInterval(displayTime, 1000);
  }

  function stopClock() {
    clearInterval(waitTimer);
  }

  btnStart.onclick = startClock;
  btnStop.onclick = stopClock;
<h1>JavaScript Clock</h1>

    <div id = "calendarBox">
      <!-- OUTPUT TIME VALUES -->
      <p class = "timeDisplay">
        <span id = "hoursOut">00:</span>
        <span id = "minsOut">00:</span>
        <span id = "secsOut">00</span>
      </p>

      <!-- BUTTON SET -->
      <input id = "btnStart" type = "button" value = "START" />
      <input id = "btnStop" type = "button" value = "STOP" />
    </div>

Возможное решение — предотвратить проблему до того, как она возникнет. Вы можете проверить работающий таймер (Есть ли способ проверить, использует ли переменная setInterval()?).

В этом случае вы могли бы просто иметь глобальную переменную таймера var timer = false с добавлением проверки к функции start. Затем функция stop установит для переменной таймера значение false.

     function startClock() {
        if (!timer){
          timer = true
          waitTimer = setInterval(displayTime, 1000);
        }
        else return
      }
    
      function stopClock() {
        clearInterval(waitTimer);
        timer = false
      }

Другие вопросы по теме