⏱️ 在线秒表(带分段计时)
按下开始后,这个工具并不会真的以三十毫秒为单位累加小块的时间。它会在你按下开始的瞬间记录下performance.now()的精确读数,然后在每次重绘时,用当前的读数减去之前存储的数值,从而得到经过的时间——这个数值是每次重新计算的,而不是累积的。这个区别很重要,因为浏览器会故意在后台标签页中减缓setInterval的速度以节省电量,而这正是自制计时器出现偏差或丢失秒数的经典原因。由于这个秒表总是通过时间戳的差值来计算数值,而不是计算实际触发的tick数量,因此当你返回标签页时,即使已经离开了几分钟,显示的时间也会立即回到正确的数值。
秒表是一个免费的浏览器计时器,它通过将单调的performance.now()时钟与存储的开始时间戳进行比较,来跟踪经过的时间,而不是通过计算setInterval的tick次数,因此即使浏览器减缓标签页的屏幕更新,显示的数字仍然保持准确。
隐私优先设计. 此工具完全在您的浏览器中运行 — 您输入的任何内容都不会上传或存储,并且可以离线使用。
关于
在内部,有三个状态:一个以毫秒为单位的累积的`elapsed`值,一个`startAt`快照,即你按下开始时的`performance.now()`读数,以及一个布尔值`running`标志。生成屏幕上数字的函数仅仅是`elapsed`加上,如果正在运行,当前时间与`startAt`的差值。一个`setInterval`每30毫秒调用一次这个函数,仅仅是为了刷新显示——这个间隔本身并不携带任何时间信息,它只是一个刷新触发器。这是构建秒表的正确方法,直接避免了常见的计时器错误,即计时器在每次tick时添加一个固定增量,一旦tick被延迟、跳过或合并,就会慢慢出现偏差。
这个设计选择也决定了当你切换到其他标签页时会发生什么。浏览器会减缓后台标签页的计时器以节省CPU和电池——一个设置为每30毫秒的`setInterval`在标签页不可见时可能会被延迟到每秒一次或更慢。在这个秒表中,这仅影响屏幕上数字刷新的频率;底层的数学计算(当前时间戳减去开始时间戳,加上之前累积的时间)并不关心跳过了多少次刷新。切换回标签页后,下一次刷新会显示精确的经过时间——由于减缓,时间没有丢失或增加,只是在你查看其他内容时,秒数的流动不够平滑。
使用`performance.now()`而不是`Date.now()`也是完成这项任务的正确选择,而不是偶然的细节。`Date.now()`反映了你的系统时钟,而系统时钟可能会跳跃——例如,笔记本电脑从睡眠中唤醒并与NTP服务器同步,手动更改时钟,或调整夏令时,都可能导致`Date.now()`在会话中向前或甚至向后跳跃。`performance.now()`被定义为单调时钟:它始终以稳定的速度递增,不受这些修正的影响,这正是秒表所需的确保,而普通系统时钟计时器不具备这一特性。
诚实的限制是持久性,而这里没有。这个构建将`elapsed`和`laps`数组作为普通的JavaScript变量存储在页面内存中——源代码中没有任何地方调用localStorage或这个网站自己的`Playground.store()`辅助函数,其他Toolio工具使用它来在重新加载后继续运行。这意味着刷新页面、关闭标签页或点击到其他工具,会立即永久地清除你正在运行的时间和所有记录的圈数。没有“恢复上一节”的功能,也没有跨设备同步,也没有任何备份,因为从一开始就没有将任何内容写入存储。如果你的圈数历史实际上对你很重要——比如锻炼日志或一组演示时间——在导航离开之前,将这些数字记录下来或截图,因为这个页面不会为你记住它们。
如何使用
- 点击"开始"——按钮立即重新标记为"暂停",屏幕上的时钟开始以实时速度上升,每30毫秒刷新一次。
- 在运行时的任何时候点击"圈数",以快照当前的经过时间;新的条目会固定在圈数列表的顶部,并显示其分段时间(自上一个圈数以来的时间)和累计总时间。
- 再次点击同一个按钮,现在标记为"暂停",以冻结显示——经过时间在内部被保存,没有丢失,按钮恢复为"开始"。
- 再次点击"开始"以从你离开的地方继续计时,而不是从零开始。
- 点击"重置"以将显示归零,清除所有记录的圈数,并将两个按钮恢复为初始标签——这也是开始新会话的唯一方法,因为没有保存功能来保护旧会话。
常见问题
- 这个秒表实际上是如何在内部测量时间的?
- 它在你按下开始的瞬间读取一次`performance.now()`,并存储这个数字。从那时起,屏幕上的数值仅仅是"已经累积的时间"加上"当前`performance.now()`减去那个存储的开始时间戳"——在每次30毫秒的刷新时重新计算。它从不简单地在每次tick时将一个固定的+30ms加到运行的总数上,这是许多自制计时器慢慢偏离同步的快捷方式。
- 如果我在它运行时切换到另一个浏览器标签页,时间会发生什么变化?
- 后台标签页会被减缓——浏览器可以将一个30毫秒的`setInterval`延迟到每秒一次或更慢,以节省CPU和电池,因此屏幕上的数字可能在你离开时看起来冻结或跳跃。但由于这个秒表始终通过时间戳差值计算经过时间,而不是计算触发了多少tick,因此切换回标签页会使下一次刷新显示精确的正确经过时间。你不会因为减缓而损失或增加时间——只是在你看不到时,视觉的流畅度会受到影响。
- 为什么使用`performance.now()`而不是`Date.now()`——这真的重要吗?
- 是的。`Date.now()`反映了你的系统时钟,而系统时钟可能会向前或向后跳跃——例如,笔记本电脑从睡眠中唤醒并与NTP服务器同步后,或者如果系统时钟被手动更改。`performance.now()`是一个单调时钟,它始终以稳定的速度递增,不受这些修正的影响,这正是秒表所需的属性,这个构建使用了正确的时钟。
- 它是否在任何地方保存我的经过时间或圈数历史?
- 不——与其他一些Toolio工具不同,它根本不使用浏览器的localStorage来存储这些数据。你看到的一切只存在于页面内存中,只要这个特定的标签页保持打开。刷新页面、关闭标签页或导航到其他工具,你的经过时间和所有圈数都会永远消失;没有撤销也没有自动保存,因为从一开始就没有将任何内容写入存储。如果你需要记录,离开前请将数字记录下来或截图。
- 圈数是否有上限,每个圈数行上的两个数字分别代表什么?
- 没有上限——列表会继续增长,最新的圈数会固定在顶部。每一行显示两个数字:分段时间,以强调颜色显示,是自上一个圈数以来经过的时间;总时间,以灰色显示,是自你按下开始以来的累计时间。这种配对让你可以判断单个片段——一次锻炼间隔,一次演讲部分——而不会失去对整体运行的跟踪。
- 此工具会上传我的数据吗?
- 不会。所有操作都在您的浏览器中完成,因此您的数据永远不会离开您的设备 — 甚至在页面加载后也可以离线使用。