有一天女朋友跟我抱怨:工作里被各种链接折腾得头大,飞书和浏览器之间来回切窗口,一会忘了看哪个,心情都被搅乱了。我回头一想------我也一样,办公室每个人都被链接淹没。
同事丢来的需求文档、群里转的会议记录、GitLab 的 MR 链接、还有那些永远刷不完的通知------每点一个链接就得在聊天工具和浏览器之间跳转,回来后一秒钟就忘了"本来要点哪个、看哪个"。更别提那些收集了一堆好文章想集中看,或者别人发来一串链接让你"挑哪个好"的时候,光是打开就要折腾半天。
这不是注意力不集中,是工具没有帮你省掉这些无意义的切换。
于是我做了一个极简 Chrome 插件: Open‑All 。它只做一件事------把你所有网址一次性在新窗口打开。你复制粘贴一次,它把链接都整齐地摆在新标签页里,你只要从左到右按顺序看就行。简单、直接,让你把注意力放在真正重要的事情上
先看效果:一键打开多个链接

这些痛点你肯定也遇到过
每天都在经历的折磨
- 来回切应用 :复制、粘贴、点开、切回来,这套动作做一遍就够烦的了
- 容易忘事 :打开到第几个了?这个看过没?脑子根本记不住
- 启动成本高 :一想到要一个个点开,就懒得开始了
- 没法对比 :想要横向比较几个方案,但打开都费劲
具体什么时候最痛苦
- 收集的文章想一口气看完 :平时存了一堆好文章,周末想集中看,结果光打开就累了
- 别人让你帮忙选 :同事发来几个方案链接问你觉得哪个好,你得全部打开才能比较
- 代码 Review :GitLab 上好几个 MR 要看,还有相关的 Issue 和 CI 结果
- 开会前准备 :会议文档、背景资料、相关链接,都得提前打开看看
我的解决方案
设计思路很简单
- 就解决一个问题 :批量打开链接,不搞那些花里胡哨的功能
- 零学习成本 :会复制粘贴就会用
- 让你专注 :少折腾,多干活
能干什么
- 把一堆链接一次性在新窗口打开
- 自动保存你输入的内容,不怕误关
- 界面超简单,点两下就搞定
技术实现
项目结构
bash
shiba-cursor
├── manifest.json # 扩展的"身份证"
├── popup.html # 弹窗样式
└── popup.js # 弹窗交互
文件说明:
- manifest.json:扩展身份信息
- popup.html:弹窗样式
- popup.js:弹窗交互
🚀 浏览项目的完整代码可以点击这里 github.com/Teernage/op...,如果对你有帮助欢迎Star。
动手实现
第一步:创建项目文件
创建文件夹 open-all
创建manifest.json文件
json
{
"manifest_version": 3,
"name": "批量打开URL",
"version": "1.0",
"description": "输入多个URL,一键在新窗口中打开",
"permissions": [
"tabs",
"storage"
],
"action": {
"default_popup": "popup.html",
"default_title": "批量打开URL"
}
}
创建popup.html文件
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 320px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
sans-serif;
color: #333;
}
.container {
background: rgba(255, 255, 255, 0.95);
padding: 20px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.title {
font-size: 18px;
font-weight: 600;
text-align: center;
margin-bottom: 16px;
color: #1d1d1f;
letter-spacing: -0.5px;
}
#urlInput {
width: 100%;
height: 140px;
padding: 12px;
border: 2px solid #e5e5e7;
border-radius: 12px;
font-size: 14px;
font-family: 'SF Mono', Monaco, monospace;
resize: none;
background: #fafafa;
transition: all 0.2s ease;
line-height: 1.4;
}
#urlInput:focus {
outline: none;
border-color: #007aff;
background: #fff;
box-shadow: 0 0 0 4px rgba(0, 122, 255, 0.1);
}
#urlInput::placeholder {
color: #8e8e93;
font-size: 13px;
}
.button-group {
display: flex;
gap: 8px;
margin-top: 16px;
}
button {
flex: 1;
padding: 12px 16px;
border: none;
border-radius: 10px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
font-family: inherit;
}
#openBtn {
background: linear-gradient(135deg, #007aff 0%, #0051d5 100%);
color: white;
box-shadow: 0 2px 8px rgba(0, 122, 255, 0.3);
}
#openBtn:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 122, 255, 0.4);
}
#openBtn:active {
transform: translateY(0);
}
#clearBtn {
background: #f2f2f7;
color: #8e8e93;
border: 1px solid #e5e5e7;
}
#clearBtn:hover {
background: #e5e5ea;
color: #636366;
}
#status {
margin-top: 12px;
padding: 8px 12px;
border-radius: 8px;
font-size: 12px;
text-align: center;
display: none;
background: rgba(52, 199, 89, 0.1);
color: #30d158;
border: 1px solid rgba(52, 199, 89, 0.2);
}
.tip {
font-size: 11px;
color: #8e8e93;
text-align: center;
margin-top: 8px;
line-height: 1.3;
}
</style>
</head>
<body>
<div class="container">
<div class="title">批量打开 URL</div>
<textarea
id="urlInput"
placeholder="输入 URL,每行一个:
https://www.apple.com
https://www.github.com
https://www.google.com"
></textarea>
<div class="button-group">
<button id="clearBtn">清空</button>
<button id="openBtn">打开</button>
</div>
<div class="tip">输入会自动保存,打开后自动清空</div>
<div id="status"></div>
</div>
<script src="popup.js"></script>
</body>
</html>
创建popup.js文件
js
document.addEventListener('DOMContentLoaded', function() {
const urlInput = document.getElementById('urlInput');
const openBtn = document.getElementById('openBtn');
const clearBtn = document.getElementById('clearBtn');
const status = document.getElementById('status');
// 恢复上次保存的输入
chrome.storage.local.get(['savedUrls'], function(result) {
if (result.savedUrls) {
urlInput.value = result.savedUrls;
}
});
// 自动保存输入内容
urlInput.addEventListener('input', function() {
chrome.storage.local.set({savedUrls: urlInput.value});
});
// 清空按钮
clearBtn.addEventListener('click', function() {
urlInput.value = '';
chrome.storage.local.remove(['savedUrls']);
showStatus('已清空');
});
// 打开URL按钮
openBtn.addEventListener('click', function() {
const urls = getUrls(urlInput.value);
if (urls.length === 0) {
showStatus('请输入有效的URL');
return;
}
// 创建新窗口并打开所有URL
chrome.windows.create({url: urls[0]}, function(window) {
for (let i = 1; i < urls.length; i++) {
chrome.tabs.create({
windowId: window.id,
url: urls[i],
active: false
});
}
// 成功打开后清空输入并移除存储
urlInput.value = '';
chrome.storage.local.remove(['savedUrls']);
showStatus(`已打开 ${urls.length} 个URL`);
});
});
// 解析URL
function getUrls(input) {
return input.split('\n')
.map(line => line.trim())
.filter(line => line && (line.startsWith('http://') || line.startsWith('https://')));
}
// 显示状态
function showStatus(message) {
status.textContent = message;
status.style.display = 'block';
setTimeout(() => {
status.style.display = 'none';
}, 2000);
}
});
第二步:安装扩展

- 打开Chrome浏览器
- 地址栏输入:
chrome://extensions/ - 打开右上角"开发者模式"
- 点击"加载已解压的扩展程序"
- 选择刚才的文件夹,然后确定
- 固定扩展
- 点击扩展图标即可使用
最后想说的
这个插件功能很简单,但解决的是我们每天都会遇到的真实问题。它不会让你的工作效率翻倍,但能让你少一些无聊的重复操作,多一些专注的时间。
我和女朋友现在用着都挺爽的,希望也能帮到你。如果你也有类似的困扰,试试看吧,有什么想法也欢迎在评论区聊聊。
你最希望下个版本加什么功能?评论区告诉我!