Popup 介面設計與 Options 儲存狀態
當使用者安裝了你的擴充套件後,他們最常互動的地方就是瀏覽器右上角的圖示。點擊該圖示所彈出的小視窗,我們稱為 Popup;而如果使用者需要進行進階的帳號綁定或參數調整,通常會引導他們前往一個獨立的全螢幕網頁,稱為 Options Page。
這堂課我們將學習如何設計這兩個最重要的 UI 介面,並讓它們能夠記憶使用者的設定。
1. 打造精美的 Popup 視窗
在 manifest.json 中,我們透過 action.default_popup 來指定彈出視窗的 HTML 檔案。
這個 HTML 檔案其實與一般的網頁開發完全相同,你可以引入 CSS 框架(如 Tailwind CSS 的 CDN,或是打包後的檔案),甚至可以使用 React/Vue 等前端框架來撰寫。
[!WARNING] CSP (內容安全策略) 限制 Chrome Extension 有非常嚴格的資安限制。你無法在 HTML 中直接寫
<script> alert(1); </script>這種 inline script。所有的 JavaScript 都必須以外部檔案 (<script src="popup.js"></script>) 的方式引入。
動態獲取當前分頁資訊
Popup 最常見的功能就是針對「使用者正在看的網頁」進行操作。要取得當前分頁的資訊,我們可以使用 chrome.tabs API:
// popup.js
document.addEventListener('DOMContentLoaded', async () => {
// 查詢當前處於 active 狀態且在當前視窗的分頁
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
if (tab) {
const urlDisplay = document.getElementById('url-display');
urlDisplay.innerText = tab.url; // 將網址顯示在 Popup 介面上
}
});
注意:呼叫此 API 需要在 manifest 中申請 "activeTab" 或是 "tabs" 權限。
2. 實作 Options 設定頁面
如果你的套件需要讓使用者輸入 API Key、選擇顏色主題、或是設定黑名單,一個小小的 Popup 是不夠用的。我們需要建立一個專屬的設定頁面。
首先,在 manifest.json 中宣告 Options 頁面:
{
"options_ui": {
"page": "options.html",
"open_in_tab": true
}
}
設定 open_in_tab: true 會讓這個頁面在一個全新的大分頁中開啟,體驗會好很多。
3. 使用 chrome.storage 保存使用者偏好
不論是在 Popup 還是 Options 頁面,當使用者更改了設定,我們必須將這些設定保存下來,確保下次開啟瀏覽器時設定不會消失。
在擴充套件中,我們不使用 localStorage,因為它很容易在清除瀏覽資料時被刪除,而且不同的 Context (Popup, Content Script, Background) 之間很難共享。
我們必須使用 chrome.storage API。它分為兩種主要模式:
chrome.storage.local:資料只存在這台電腦。容量上限為 5MB (可申請無上限)。chrome.storage.sync:資料會跟著使用者的 Google 帳號自動同步到他其他的電腦上!容量上限較小 (100KB),非常適合存 API Key 或簡單的布林值設定。
實戰:儲存與讀取 API Key
以下是一個簡單的 Options 頁面邏輯範例:
儲存資料 (寫入 Sync Storage):
// options.js
const saveBtn = document.getElementById('save-btn');
const apiKeyInput = document.getElementById('api-key-input');
saveBtn.addEventListener('click', () => {
const userApiKey = apiKeyInput.value;
// 將資料存入 sync storage
chrome.storage.sync.set({ openAiApiKey: userApiKey }, () => {
console.log('設定已儲存!');
// 可以顯示一個提示訊息給使用者
const status = document.getElementById('status-msg');
status.innerText = '儲存成功!';
setTimeout(() => { status.innerText = ''; }, 2000);
});
});
初始化頁面時讀取資料:
// 當選項頁面載入時,把之前存的 Key 拿出來顯示在輸入框中
document.addEventListener('DOMContentLoaded', () => {
chrome.storage.sync.get(['openAiApiKey'], (result) => {
if (result.openAiApiKey) {
document.getElementById('api-key-input').value = result.openAiApiKey;
}
});
});
監聽 Storage 的改變
這個 API 最強大的地方在於,它允許其他的元件(例如你的 Content Script)即時監聽設定的改變!
如果使用者在 Options 頁面切換了「暗黑模式」開關,你的 Content Script 可以立刻收到通知並改變網頁顏色:
// 在 content.js 中
chrome.storage.onChanged.addListener((changes, namespace) => {
for (let [key, { oldValue, newValue }] of Object.entries(changes)) {
if (key === 'darkMode') {
console.log(`暗黑模式狀態從 ${oldValue} 變更為 ${newValue}`);
// 執行變更顏色的邏輯
toggleDarkModeUI(newValue);
}
}
});
把 UI 介面與 chrome.storage 完美結合,你的擴充套件就具備了完整產品的雛形。
在最後一個章節,我們將進入最激動人心的環節:如何把這個套件變現,並正式上架到全世界的 Chrome Web Store!