🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付

女朋友被連結折磨瘋了,我寫了個工具一鍵解救

有一天女朋友跟我抱怨:工作裡被各種連結折騰得頭大,飛書和瀏覽器之間來回切窗口,一會忘了看哪個,心情都被攪亂了。我回頭一想——我也一樣,辦公室每個人都被連結淹沒。

“同事丟來的需求文件、群裡轉的會議記錄、GitLab 的 MR 連結、還有那些永遠刷不完的通知——每點一個連結就得在聊天工具和瀏覽器之間跳轉,回來後一秒鐘就忘了'本來要點哪個、看哪個'。更別提那些收集了一堆好文章想集中看,或者別人發來一串連結讓你'挑哪個好'的時候,光是打開就要折騰半天。

這不是注意力不集中,是工具沒有幫你省掉這些無意義的切換。

於是我做了一個極簡 Chrome 擴展: Open‑All 。它只做一件事——把你所有網址一次性在新窗口打開。你複製粘貼一次,它把連結都整齊地擺在新標籤頁裡,你只要從左到右按順序看就行。簡單、直接,讓你把注意力放在真正重要的事情上。

先看效果:一鍵打開多個連結

批量打開所有url.gif

這些痛點你肯定也遇到過

每天都在經歷的折磨

  • 瀏覽器和飛書、企微、釘釘來回切應用:複製連結、粘貼、點開、切回來,這套動作做一遍就夠煩的了。
  • 容易忘事:打開到第幾個連結了?這個看過沒?腦子根本記不住。
  • 啟動成本高:一想到連結要一個個點開,就懶得開始了。
  • 沒法對比:想要橫向比較幾個方案,但打開方案連結都費勁。

具體什麼時候最痛苦

  1. 收集的文章想一口氣看完:平時存了一堆好文章,週末想集中看,結果光打開就累了。
  2. 別人讓你幫忙選:同事發來幾個方案連結問你覺得哪個好,你得全部打開才能比較。
  3. 代碼 Review:GitLab 上好幾個 MR 要看,還有相關的 Issue 和 CI 結果。
  4. 開會前準備:會議文件、背景資料、相關連結,都得提前打開看看。

我的解決方案

設計思路很簡單

  • 就解決一個問題:批量打開連結,不搞那些花裡胡哨的功能。
  • 零學習成本:會複製粘貼就會用。
  • 讓你專注:少折騰,多幹活。

能幹什麼

  • 把一堆連結一次性在新窗口打開。
  • 自動保存你輸入的內容,不怕誤關。
  • 界面超簡單,點兩下就搞定。

技術實現

專案結構

shiba-cursor
├── manifest.json      # 擴展的"身份證"
├── popup.html         # 彈窗樣式
└── popup.js           # 彈窗互動

文件說明:

  • manifest.json:擴展身份信息。
  • popup.html:彈窗樣式。
  • popup.js:彈窗互動。

🚀 瀏覽專案的完整代碼可以點擊這裡 github.com/Teernage/op…,如果對你有幫助歡迎Star。

動手實現

第一步:創建專案文件

  1. 創建資料夾 open-all
  2. 創建manifest.json文件
{
  "manifest_version": 3,
  "name": "批量打開URL",
  "version": "1.0",
  "description": "輸入多個URL,一鍵在新窗口中打開",
  "permissions": [
    "tabs",
    "storage"
  ],
  "action": {
    "default_popup": "popup.html",
    "default_title": "批量打開URL"
  }
}
  1. 創建popup.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>
  1. 創建popup.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);
  }
});

第二步:安裝擴展

安裝open all使用.gif

  1. 打開Chrome瀏覽器。
  2. 地址欄輸入:chrome://extensions/
  3. 打開右上角"開發者模式"。
  4. 點擊"加載已解壓的擴展程序"。
  5. 選擇剛才的資料夾,然後確定。
  6. 固定擴展。
  7. 點擊擴展圖標即可使用。

最後想說的

這個插件功能很簡單,但解決的是我們每天都會遇到的真實問題。它不會讓你的工作效率翻倍,但能讓你少一些無聊的重複操作,多一些專注的時間。

我和女朋友現在用著都挺爽的,希望也能幫到你。如果你也有類似的困擾,試試看吧,有什麼想法也歡迎在評論區聊聊。

你最希望下個版本加什麼功能?評論區告訴我!

如果覺得對您有幫助,歡迎點讚 👍 收藏 ⭐ 關注 🔔 支持一下!
往期實戰推薦:


原文出處:https://juejin.cn/post/7566677296801071155


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝25   💬5   ❤️7
780
🥈
我愛JS
📝2   💬7   ❤️3
118
🥉
酷豪
1
#5
1
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付