本實戰課程專為初學者設計。我們將使用 FALO Instagram Video Enhancer v1.0.1 作為範例,手把手帶您學習如何在開發者模式下部署、載入並測試 Chrome 擴充功能。
下載上述 ZIP 檔後,在您的電腦上進行解壓縮,您會得到一個名為 ig-video-enhancer-extension 的專案目錄。
開啟 Google Chrome 瀏覽器,在網址列中輸入 chrome://extensions/ 並按下 Enter 鍵,或從右上角選單進入「延伸功能」 > 「管理延伸功能」。
在擴充功能管理頁面的右上方,找到「開發人員模式」(Developer mode) 開關,並將其切換為啟用狀態。
點擊頁面左上方浮現的 「載入未封裝項目」(Load unpacked) 按鈕。
在彈出的視窗中,選取剛才解壓縮的 ig-video-enhancer-extension 資料夾,然後點擊「選取」或「確認」。
若畫面上成功出現 FALO Instagram Video Enhancer v1.0.1 記憶卡片,並顯示 ID 與狀態開關已啟用,即表示您的外掛已順利部署!
本範例特別實作了可在畫面上任意拖曳的 **智慧遙控器**,內建 OLED 狀態同步螢幕、播放進度條、音量與速度調節按鈕,並支援隨點隨切的 5 種專屬色彩主題:
當您點擊播放中的 Instagram 影片或模擬影片時,可以直接使用鍵盤以下快捷鍵控制影片,每次變更時畫面上皆會顯示精美的 macOS 風格 HUD 浮現卡:
| 鍵盤按鍵 | 功能描述 |
|---|---|
| 1 | 切換播放 / 暫停狀態 |
| 2 / 3 | 降低音量 5% / 增加音量 5% |
| 4 | 快速靜音 / 取消靜音 |
| 5 / 6 | 減慢播放速度 / 加快播放速度 (以 0.25x 為一級,範圍 0.5x - 2.0x) |
| ← / → (左右方向鍵) | 影片倒帶 5 秒 / 快進 5 秒 |
在開發如 Instagram 這類大型、高動態的 SPA (單頁應用) 時,官方前端框架(React/Relay)有一套非常嚴密的事件與播放狀態管理機制。外掛因為不是呼叫原生 API,而是採取「DOM 植入與覆蓋 (DOM Injection & Overlay)」的外部強行操作手段,如果沒有處理好瀏覽器的事件流(Event Flow),就容易導致按鈕點擊「卡卡的」、操作不同步、甚至是點擊時觸發 IG 原生暫停與靜音的 Bug。以下為您公開本專案用來突破限制的「黑科技小技巧」:
開發痛點: 當您點選自製遙控器的按鈕、或拖曳自製的播放進度條時,點擊事件會「冒泡 (Bubble)」傳遞給底層 Instagram 原生的影片容器,觸發 IG 本身的 Click 事件,導致影片又被暫停或靜音,操作感極度不流暢。
黑科技小技巧: 外掛在自製的 progress-container 與遙控器按鈕上註冊 pointerdown 與 click 事件,並在第一時間調用:
e.stopPropagation(); // 阻止事件冒泡,不讓點擊穿透 e.preventDefault(); // 阻止瀏覽器的預設點擊暫停行為
這就像是在 IG 原有介面之上,強行蓋了一層「事件防護罩」,確保遙控器的指令是單向且獨立地直接送給 HTML5 <video>,完全隔絕 IG 原生 JS 監聽器的干擾。
開發痛點: 當使用者快速上下滑動 IG 牆時,DOM 中其實會殘留好幾個 <video> 標籤。這時按下快捷鍵(如「1」播放暫停),外掛要如何精準判定此時該控制哪一個影片,而不是讓看不見的影片在背景亂播?
黑科技小技巧: 外掛並不固定綁定單一 Video,而是在事件觸發時動態計算!透過實時調用 getBoundingClientRect() 計算當前所有影片在 Viewport 中的可見面積:
// 計算可見寬高乘積,找出目前佔螢幕面積最大的 video
const visibleHeight = Math.max(0, visibleBottom - visibleTop);
const visibleWidth = Math.max(0, visibleRight - visibleLeft);
const visibleArea = visibleHeight * visibleWidth;
if (visibleArea > maxVisibleArea) { ... }
這套算法能在毫秒間定位出「目前畫面上可見佔比最大」的 Reels 影片,將熱鍵操作目標動態綁定在它身上,完美解決滑動時的多影片控制衝突。
開發痛點: Chrome 擴充功能的 chrome.storage.sync 只能在被載入成正式外掛時運行。如果在一般網頁(例如本地教學測試頁面 mock_instagram.html)測試,就會因為找不到 chrome API 而直接報錯崩潰。
黑科技小技巧: 外掛實作了巧妙的介面適配器模式 (Adapter Pattern):
const storage = {
get: (defaults, callback) => {
if (typeof chrome !== 'undefined' && chrome.storage) {
chrome.storage.sync.get(defaults, callback);
} else {
// 降級 fallback 支援普通網頁的 localStorage
// ...
}
}
};
這使同一份程式碼同時具備「外掛端」與「網頁 PoC 端」的相容性,讓學生即使不載入外掛,也能在本地測試網頁上完整體驗遙控器的倍速、主題切換等功能!
開發痛點: 遙控器上的 OLED 螢幕需要顯示目前影片的精確播放進度和倍速。如果每個 DOM 更新都綁定高頻率的 timeupdate 事件,可能導致網頁重繪 (Repaint) 過度頻繁而產生掉幀、卡頓。
黑科技小技巧: 程式在遙控器內部使用了一個 250ms 的輕量級定時循環,實時渲染 OLED 螢幕:
setInterval(() => {
const video = getActiveVideo();
if (video) {
screenSpeed.textContent = `SPEED: ${video.playbackRate.toFixed(2)}x`;
screenTime.textContent = `${formatTime(video.currentTime)} / ${formatTime(video.duration)}`;
}
}, 250);
配合 chrome.storage.onChanged 的全域監聽,當使用者在分頁 A 調整了速度或靜音狀態,設定會瞬間寫入 Storage 並廣播,讓所有分頁的遙控器狀態即時同步。
在此特別致謝 Chrome 線上應用程式商店的 Progress Bar for Instagram 外掛,其創新的設計為本教學專案奠定了關鍵的思路。我們在保留原版優良基礎的同時,透過與 AI 協同進行了深度功能重構與進化:
| 功能模組 | 原版核心功能 (靈感來源) | FALO 二創進化版 (AI 協同重構) |
|---|---|---|
| 影片進度條 (Timeline) | 在 Instagram 影片下方植入進度條,點擊可拖拽調整播放進度。 | 保留進度拖曳,並新增滑鼠懸停時即時計算並顯示 hover 時刻的 精準 Tooltip 時間預覽。 |
| 音量控制 (Volume) | 基本音量調整功能。 | 在 IG 原生靜音按鈕上強行注入 CSS Hover 垂直音量控制條,支援點選與拖曳微調。 |
| 實體控制器 (Controller) | 無實體遙控器面板。 | 新增 智慧懸浮遙控器,內建 OLED 螢幕即時回傳進度,支援 5 種色彩主題及拖拽坐標鎖定。 |
| 操作回饋 (HUD Display) | 無螢幕顯示提示。 | 新增 macOS 風格的 On-Screen HUD 浮現卡,每次調整速度、音量或快進退時即時彈出回饋。 |
Chrome 外掛程式的本質是瀏覽器中的「輕量級網頁應用」。在最新的 Manifest V3 (MV3) 規範中,擴充功能主要由四個不同執行環境的元件組成。理解這些元件的權限與邊界,是與 AI 協同開發時的核心基本功。
執行環境: 網頁瀏覽分頁中(宿主網頁環境)。
核心能力: 可以讀取、修改目標網頁的 HTML (DOM) 與 CSS。
AI 開發關鍵: 它是外掛中唯一能碰觸到網頁播放器、加上控制條的元件。如果需要讓 AI 對網頁元素進行修改,請明確命令 AI 將代碼寫在 content.js。
獨立世界機制 (Isolated World): 它與網頁共用同一個 HTML DOM,但雙方的 JavaScript 變數完全隔離,網頁原生的 JS 腳本無法讀取或竄改外掛腳本的變數,確保安全。
執行環境: 點擊工具列圖示時顯示的獨立沙盒視窗。
核心能力: 具備自己獨立的 HTML、CSS 與 JS,相當於一個微型網頁。
限制: **無法直接存取目標網頁的 DOM!** 如果 Popup 內的按鈕需要控制影片,必須透過訊息發送給 content.js。
AI 開發關鍵: 當要讓使用者切換設定(如:是否顯示遙控器、是否啟用快速鍵)時,請叫 AI 在 Popup 中建立 UI 控制項與訊息傳遞發送器。
執行環境: 瀏覽器後台。
核心能力: 監聽全域事件(如安裝、更新、特定分頁建立與關閉)。
重要限制: **不支援 window 或是 document 物件**,沒有 UI 畫面,在 MV3 中以 Service Worker 運行,閒置時會自動暫停釋放記憶體。
AI 開發關鍵: 外掛載入、初始化設定值(如音量或快照)、處理跨網域的 background 網絡請求等全域不間斷邏輯,才需要寫在 background.js。
功能用途: 設定外掛的基本屬性、註冊元件、以及聲明安全權限。
AI 開發關鍵: AI 每次撰寫新的外掛,一定要最先要求它提供 manifest.json。如果在代碼中使用 chrome.storage 卻發現無效,通常是因為 AI 忘記在 manifest 的 permissions 陣列中加上 "storage"。
在使用 AI(例如 Gemini、Claude)進行外掛開發時,請直接複製以下經過優化的結構化提示詞(Prompt),並依照您的點子進行微調,即可大幅提升 AI 生成代碼的成功率:
由於網路上充斥大量舊版 Manifest V2 (MV2) 外掛教學,AI 常常會不小心混用過時語法。當在 Chrome 載入外掛報錯時,請對照下表並使用右側提示詞命令 AI 修改:
| 舊版 MV2 寫法 (AI 常犯錯) | 新版 MV3 寫法 (正確標準) | 糾正 AI 的提示詞 |
|---|---|---|
| "manifest_version": 2 | "manifest_version": 3 | "Chrome 已經全面廢棄 MV2,請將 `manifest_version` 升級為 3,並依 MV3 規範調整所有欄位。" |
| "background": { "scripts": ["bg.js"] } | "background": { "service_worker": "bg.js" } | "在 MV3 中,背景頁已改為 Service Worker,請將背景欄位改為 `service_worker` 單一檔案宣告。" |
| "browser_action": { ... } | "action": { ... } | "MV3 中已將 `browser_action` 與 `page_action` 合併為統一的 `action` 欄位,請協助修正。" |
| chrome.extension.getURL() | chrome.runtime.getURL() | "請將過時的 `chrome.extension` 命名空間替換為最新規範的 `chrome.runtime` 寫法。" |