简体中文 | English
让两个 Chrome 页面同步滚动,适合原文与译文、文档与注释、接口文档与代码等双页对照场景。
CoScroll Tabs 是一个基于 Manifest V3 的 Chrome 扩展。它既能自动识别 Chrome 原生拆分视图,也能手动连接同一窗口或不同窗口中的任意两个普通标签页。所有联动逻辑都在本地运行,不上传浏览记录或页面内容。
- 拆分视图自动连接:在 Chrome 140 及以上版本中自动识别原生拆分视图的两个页面。
- 跨 Tab、跨窗口联动:可手动选择页面 B;即使目标页位于后台窗口,也能继续同步。
- 双向同步:滚动任意一侧都能驱动另一侧。
- 主滚动区识别:自动识别页面正文和常见的嵌套滚动容器。
- 状态恢复:页面刷新后恢复配对、模式和关联点;关闭配对页面后自动清理状态。
- 快捷控制:支持暂停、恢复、断开以及
Alt+Shift+S快捷键。 - 本地优先:没有服务器、统计分析代码或运行时第三方依赖。
| 模式 | 工作方式 | 适合场景 |
|---|---|---|
| 同速 | 两页移动相同的像素距离 | 布局和行高基本一致的页面 |
| 比例 | 两页保持相同的阅读进度 | 篇幅不同但结构相近的页面 |
| 关联点 | 按你记录的对应位置分段映射 | 原文与译文、不同排版或章节长度差异较大的页面 |
关联点模式不会退回比例模式。没有有效关联点时,扩展会保持暂停并提示先完成校准,避免错误联动。
当前版本通过 Chrome 开发者模式安装。
- 打开仓库右侧的 Releases。
- 下载最新版本的
CoScroll-Tabs-vX.Y.Z.zip安装包。 - 将 ZIP 完整解压到一个固定目录,不要直接在压缩包内加载。
- 在 Chrome 地址栏打开
chrome://extensions/。 - 打开页面右上角的 开发者模式。
- 点击 加载已解压的扩展程序,选择解压后包含
manifest.json的文件夹。 - 建议在工具栏中固定 CoScroll Tabs,方便配对和校准。
- 在 GitHub 页面点击 Code > Download ZIP,或使用 Git 克隆本仓库。
- 如果下载的是 ZIP,先将其完整解压到一个固定目录。
- 在 Chrome 地址栏打开
chrome://extensions/。 - 打开页面右上角的 开发者模式。
- 点击 加载已解压的扩展程序,选择包含
manifest.json的项目目录。 - 建议在工具栏中固定 CoScroll Tabs,方便配对和校准。
更新源码后,在 chrome://extensions/ 中找到本扩展并点击刷新按钮即可加载新版本。已经打开的网页也建议刷新一次。
Chrome 会提示扩展可以读取和更改网站数据。这是因为两个页面都需要运行滚动同步脚本;扩展不会把页面内容发送到外部服务。
- 使用 Chrome 的拆分视图打开两个页面。
- 点击扩展图标,确认已识别两个页面。
- 选择联动模式并点击连接。
- 打开页面 A,点击扩展图标。
- 选择 自选标签页,再从当前窗口或其他 Chrome 窗口选择页面 B。
- 选择联动模式并建立连接。
同一浏览器配置中的普通 Chrome 窗口可以互相联动;不同 Chrome 实例、不同用户配置以及普通窗口与无痕窗口不能共享联动状态。
- 连接两个页面并选择 关联点。扩展会暂停同步,让两页可以独立滚动。
- 分别把 A、B 两页滚到语义对应的位置。
- 打开扩展,点击 记录位置。
- 继续向下寻找对应段落并记录更多位置。关联点在两页中都必须保持从上到下的顺序。
- 点击 完成校准,关联点联动才会开启。
若不想保留本轮记录,可点击 取消校准。页面真正到达开头或结尾时,两侧会自动贴边;这些隐藏边界不会参与正文区间插值,因此不会覆盖自定义位置偏移。
关联点保存的是两页的实际滚动位置,并在相邻点之间分段插值。映射不依赖页面瞬时总高度,所以滚轮力度变化、页面动态增高或长页面加载通常不会改变已经记录的对应关系。
| 权限 | 用途 |
|---|---|
scripting |
在配对页面中启动或恢复同步脚本 |
storage |
本地保存配对状态、模式和关联点 |
<all_urls> |
支持普通网站之间的任意配对 |
- 扩展不发起业务网络请求,不包含遥测或广告代码。
- 页面 URL 仅用于在本地生成关联点配置标识;实际 URL 不会随配置明文持久化。
- 页面正文、滚动内容和浏览历史不会上传到服务器。
chrome://页面、Chrome 扩展商店、其他扩展页面和内置 PDF 查看器不允许注入脚本。- Google Docs、Figma、在线 Office、Canvas 和部分虚拟列表应用不一定使用普通 DOM 滚动,效果无法保证。
- 当前只同步顶层文档,不跨域控制 iframe 内部滚动。
- 普通窗口和无痕窗口属于不同浏览上下文,不能互相联动。
- 原生拆分视图自动识别需要 Chrome 140 及以上;较早版本仍可手动选择两个标签页。
需要 Node.js 20 或更高版本。项目没有运行时第三方依赖。
npm run check
npm test浏览器冒烟测试还需要本地可用的 Playwright,并会使用隔离的临时浏览器配置,不修改日常 Chrome 数据:
npm run test:browser可用环境变量:
CHROME_PATH:指定 Chromium/Chrome/Edge 可执行文件。HEADED=1:以有界面模式运行。NODE_PATH:Playwright 不在当前项目依赖中时,指定其node_modules路径。
测试截图输出到 tests/artifacts/,该目录不会提交到 Git。
├─ background.js # 配对、状态持久化和跨标签页消息转发
├─ content.js # 页面滚动监听、主滚动区识别和同步执行
├─ lib/scroll-mapping.js # 比例与关联点映射算法
├─ popup.* # 扩展弹窗界面和交互
├─ tests/ # 单元测试、测试页面和浏览器冒烟测试
├─ scripts/ # 静态检查和图标生成脚本
└─ docs/research.md # 技术调研与实现依据
更多实现背景见 技术调研。
本项目基于 MIT License 开源。
