一个可拖动的秒表,悬浮在页面上实时计时,单击归零并重新计时。支持视频全屏时自动重挂载,所有标签页同步计时。
- ⏱ 数字秒表显示
MM:SS - 🔄 单击归零并重新计时
- 🔗 所有标签页计时同步(chrome.storage 实时广播,任意页面操作全局生效)
- 🎯 随意拖拽到任意位置,位置自动保存(localStorage 按域名隔离)
- 🖥️ 视频全屏时秒表自动移入全屏元素,保持可见
- 🔄 自动适配单页应用(MutationObserver 监听 DOM 重建)
- 📱 支持鼠标和触摸操作
- 打开 Chrome → 进入
chrome://extensions/ - 开启"开发者模式"
- 点击"加载已解压的扩展程序",选择
draggable_timer目录
manifest.json # 扩展配置文件(Manifest V3)
content.js # 内容脚本:秒表逻辑、拖拽、全屏重挂载
styles.css # 毛玻璃药丸样式
test/
├── content.test.js # 单元测试(30 个用例,覆盖核心逻辑、storage 同步与边界条件)
└── vitest.config.js # 测试环境配置(jsdom)
package.json # 依赖与脚本(npm test 运行测试)
.gitignore # 排除 node_modules/ 等
- 拖拽:按住秒表并拖动到任意位置,松手后位置自动保存
- 计时:单击秒表归零并开始计时,再次单击重新归零
npm test测试框架 Vitest + jsdom,30 个测试覆盖:pad、formatTime、getElapsed、isValidState、applyPosition、startStopwatch、savePosition、reparentStopwatch、storage 同步及各类边界条件。
- Manifest V3,纯前端实现,无需后台脚本
position: fixed固定定位,z-index: 10000置顶- CSS
touch-action: none+backdrop-filter毛玻璃效果 - 拖拽逻辑带视口边界约束,支持鼠标和触摸事件;窗口失焦(
blur)兜底复位拖拽状态 - 跨标签同步:秒表状态存
chrome.storage.local,storage.onChanged实时广播到所有标签页 - 计时基于时间戳推算(
startElapsed + (now - startTime)),后台标签被节流时也不走偏,关闭标签页期间计时照常 - 外部数据(storage/localStorage)统一校验:
isValidState校验计时状态,位置值校验Number.isFinite并 clamp 到视口 - 全屏方案:监听
fullscreenchange/webkitfullscreenchange,将秒表容器移至document.fullscreenElement MutationObserver监听 DOM 变化,防止秒表在 SPA 路由切换时丢失- 鼠标/触摸事件提升到
document级,只注册一次避免重复绑定
- 部分受限制页面(如 chrome://)无法注入内容脚本