Javascript:如何从给定的 HH:MM:SS 开始秒表?

Posted

技术标签:

【中文标题】Javascript:如何从给定的 HH:MM:SS 开始秒表?【英文标题】:Javascript: How to start stopwatch from a given HH:MM:SS? 【发布时间】:2021-05-09 09:04:08 【问题描述】:

更新

设法从现在 01:02:03 开始​​。
startTime = new Date().getTime()-(seconds);

但是当我恢复秒表时,它不会从暂停的地方继续。 例如, 我在 00:07:45 暂停了。我想恢复它,但我得到了 00:15:30。


你好吗?希望你们今天或晚上过得愉快。

所以我这里有个小问题。我有一个秒表。我希望秒表从显示的特定时间开始运行。

例如, 现在秒表上显示的时间是 01:02:03。我希望秒表从 01:02:03 开始​​。

我对此进行了研究。它与 Epoch javascript 有关。我将 01:02:03 转换为毫秒。但它不是从 01:02:03 开始​​的。相反,它从 22:52:34 开始。

我不知道我哪里做错了。请赐教。

脚本

/*Global variables here*/

var startTime;
var updatedTime;
var difference;
var tInterval;
var savedTime;
var paused = 0;
var running = 0;
/**This function is triggered when user starts the stopwatch.**/

function startTimer()
  if(!running)
    // getting the displayed time 
    startTime = document.querySelector('#stopwatch_display').innerText;
    var a = startTime.split(':');
    var seconds = (a[0]*1000*60*60)+(a[1]*1000*60)+(a[2]*1000);
    startTime = new Date(seconds+1);
    tInterval = setInterval(getShowTime, 1);
    // change 1 to 1000 above to run script every second instead of every millisecond. one other change will be needed in the getShowTime() function below for this to work. see comment there.   
 
    paused = 0;
    running = 1;
    // Some styling here
  

/**This function is triggered when user pauses and resumes the stopwatch.**/

function pauseTimer()
  if (!difference)
    // if timer never started, don't allow pause button to do anything
   else if (!paused) 
    clearInterval(tInterval);
    savedTime = difference;
    paused = 1;
    running = 0;
    // Some styling here  
  else 
   // if the timer was already paused, when they click pause again, start the timer again
   startTimer();
  

/**This function is triggered when user resets the stopwatch.**/

function resetTimer()
  clearInterval(tInterval);
  savedTime = 0;
  difference = 0;
  paused = 0;
  running = 0;
  // Some styling here

/**This function is to display the time.**/

function getShowTime()
  updatedTime = new Date().getTime();
  if (savedTime)
    difference = (updatedTime - startTime) + savedTime;
   else 
    difference =  updatedTime - startTime;
  
  var hours = Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  var minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60));
  var seconds = Math.floor((difference % (1000 * 60)) / 1000);
  //var milliseconds = Math.floor((difference % (1000 * 60)) / 100);

  hours = (hours < 10) ? "0" + hours : hours;
  minutes = (minutes < 10) ? "0" + minutes : minutes;
  seconds = (seconds < 10) ? "0" + seconds : seconds;
  //milliseconds = (milliseconds < 100) ? (milliseconds < 10) ? "00" + milliseconds : "0" + milliseconds : milliseconds;
  timerDisplay.innerhtml = hours + ':' + minutes + ':' + seconds;

【问题讨论】:

有没有理由在 startTimer 函数中重新分配 startTime 两次?此外,该变量并未出现在该函数中。它在 getShowTimes 中使用,为什么不将它作为参数传递呢?另外,什么是 updatedTime,它是如何计算的? @Hyetigran startTime 实际上是一个全局变量。用了两次,因为我想更新startTime。 updatedTime 也是一个全局变量。嗯..如果您阅读getShowTimes 的代码 sn-p,它会通过 getTime 函数获取毫秒数。 @Hyetigran 添加了所有全局变量。 【参考方案1】:

getShowTime 应该只计算当前时间。暂停后,脚本应该依靠startTimer 继续计时器。下面是修改后的代码:

function startTimer()
  if(!running) // Check if the timer is running
    if (savedTime)  // Are we continuing after pausing?
      startTime = (+ new Date()) - savedTime; // If yes, then start from the savedTime
     else 
      // If no, get the startTime from the element
      startTime = timerDisplay.innerText;
      var a = startTime.split(':');
      var seconds = (a[0]*1000*60*60)+(a[1]*1000*60)+(a[2]*1000);
      startTime = (+ new Date()) - seconds;
    
    tInterval = setInterval(getShowTime, 1); // Start the interval
 
    running = true; // Tell the script that the stopwatch is running
  

function getShowTime()
  updatedTime = + new Date(); // Get current time. Use '+ new Date()' instead because it is much shorter.
  difference =  updatedTime - startTime; // Get the amount of seconds

  // Calculate the different parts
  var hours = Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  var minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60));
  var seconds = Math.floor((difference % (1000 * 60)) / 1000);
  //var milliseconds = Math.floor((difference % (1000 * 60)) / 100);

  hours = (hours < 10) ? "0" + hours : hours;
  minutes = (minutes < 10) ? "0" + minutes : minutes;
  seconds = (seconds < 10) ? "0" + seconds : seconds;
  //milliseconds = (milliseconds < 100) ? (milliseconds < 10) ? "00" + milliseconds : "0" + milliseconds : milliseconds;

  // Update on page
  timerDisplay.innerText = hours + ':' + minutes + ':' + seconds;


See a working example.

在控制台中输入命令。


问题

你有几个问题:

严重问题:

如果timerDisplay 元素为空或格式不正确,脚本应自动从0 开始而不是中断。 (NaN:NaN:NaN) 此问题尚未修复。 脚本依赖于获取当前时间,所以总是从当前时间开始计算。您在脚本中遇到的问题是,在startTimer 中,您执行了破坏脚本的new Date(seconds+1),因为在getShowTime 中,它从时间戳中减去了Date()。此问题已得到修复。 在暂停后继续秒表的处理应该在startTimer,而不是getShowTime。该问题已得到修复。

没有那么严重的问题

您现在应该使用+ new Date() 而不是new Date().getTime(),因为它要短得多。见this question。已修复。 秒表状态只有一个变量。在runningpaused 之间进行选择。你不能同时拥有这两者,因为它使脚本有点混乱。我相信你应该使用running,而不是paused,只需使用!running。未修复。 您应该使用truefalse 而不是01 来代替running,以使脚本更具可读性。已修复。

请尝试自己解决这些问题。

【讨论】:

要从不同于0 的时间开始,假设5 秒(5000),将元素的innerText 设置为00:00:05 或者您可以将savedTime设置为5000

以上是关于Javascript:如何从给定的 HH:MM:SS 开始秒表?的主要内容,如果未能解决你的问题,请参考以下文章

处理访问日志中的 c-dns 和 s-dns 值

如何检查到 UNIX 时间戳之间是不是有时间变化

使用从 Geolocation 发送的给定参数和对象的 Javascript 函数

即使应用程序关闭也运行时钟或计时器[重复]

如何从 JavaScript 更新 UpdatePanel

同样作为画图工具,gnuplot和matplotlib有啥异同点