面向初學者的Chrome擴充套件程式開發教程:理論部分

面向初學者的Chrome擴充套件程式開發教程:理論部分

歡迎閱讀 Chrome 瀏覽器擴充套件開發新手入門!本系列的主要目的是介紹 Chrome 擴充套件的基本概念以及如何建立擴充套件。在本系列結束時,你將使用 Javascript 製作一個 Pomodoro 計時器擴充套件。

要建立任何 Chrome 擴充套件,我們都必須依賴 Chrome 開發人員的文件。無論是 Chrome API 還是在 Chrome 網站上釋出,這都是與擴充套件相關的唯一真相來源。Chrome API 是特殊的 Javascript 函式或特殊的  manifest 檔案(稍後詳述)欄位,允許我們通過 Chrome 擴充套件與 Chrome 瀏覽器進行互動。它們由 chrome 關鍵字和 API 名稱  chrome.[API name]表示。

Chrome 開發者頁面

Manifest 檔案

manifest 檔案是每個擴充套件的核心。通過它,你可以告訴網路瀏覽器你的 Chrome 瀏覽器擴充套件應該做什麼,以及擴充套件由哪些 Javascript、Html 和 Css 檔案組成。

根據 Chrome 瀏覽器開發人員的文件

擴充套件的 manifest 是唯一必需的檔案,它必須有一個特定的檔名: manifest.json。它還必須位於擴充套件的根目錄中。清單記錄了重要的後設資料、定義了資源、宣告瞭許可權,並確定了要在後臺和頁面上執行的檔案。

這意味著 manifest 檔案是一個 JSON(Javascript 物件符號)格式的檔案。

讓我們來看一些程式碼示例:

從本文的 GitHub 程式碼庫中下載程式碼,在程式碼編輯器中開啟  chrome extension basics 資料夾。它應該是這樣的

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
📦 Chrome-Extension-Series
┣ 🎨 icon.png
📦 Chrome-Extension-Series ┣ 🎨 icon.png
📦 Chrome-Extension-Series
┣ 🎨 icon.png

建立新的 manifest.json 檔案

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
📦 chrome extension basics
┣ 🎨 icon.png
┣ 📄 **manifest.json**
📦 chrome extension basics ┣ 🎨 icon.png ┣ 📄 **manifest.json**
 📦 chrome extension basics
┣ 🎨 icon.png
┣ 📄 **manifest.json**

新增新的 manifest.json 檔案後,在其中新增以下程式碼。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"manifest_version": 3,
"name": "First Extension",
"version": "1.0.0",
"description": "My first extension",
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
}
}
{ "manifest_version": 3, "name": "First Extension", "version": "1.0.0", "description": "My first extension", "icons": { "16": "icon.png", "48": "icon.png", "128": "icon.png" } }
{
"manifest_version": 3,
"name": "First Extension",
"version": "1.0.0",
"description": "My first extension",
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
}
}

以上是 manifest 檔案的基本定義。 manifest_version 告訴瀏覽器使用哪個版本(3 是最新版本);如何定義 manifest 檔案取決於 manifest 版本。最佳做法是使用最新版本,因為舊版本已經過時。名稱欄位只是我們擴充套件的名稱。version 欄位代表 Chrome 瀏覽器擴充套件的版本。description 欄位只是 Chrome 擴充套件的描述。icons 欄位是一個物件,包含擴充套件圖示在需要時可縮放的不同尺寸。

manifest 檔案準備就緒後,就可以在瀏覽器上載入 Chrome 擴充套件了。

Chrome瀏覽器擴充套件入口

  1. 開啟 Chrome 瀏覽器
  2. 點選最右側的漢堡包圖示(如上圖所示)
  3. 點選擴充套件程式 > 管理擴充套件程式
  4. 然後開啟開發者模式
  5. 點選 “載入已解壓的擴充套件程式”
  6. 最後,選擇包含 manifest.json 檔案的  chrome extension basics 資料夾

按照上述步驟操作後,你的 Chrome 瀏覽器擴充套件應該已經載入到瀏覽器中了。如果我們檢視 Chrome 瀏覽器的擴充套件頁面,就會看到已載入的擴充套件。

Chrome擴充套件列表

點選此處瞭解有關 manifest 檔案的更多資訊

既然我們已經載入了基本擴充套件,那麼就來新增一些互動功能吧。popup 是每個擴充套件都有的互動元素;當你點選擴充套件圖示時,它就會出現在工具欄上。

根據文件:

使用 chrome.action API 控制 Google Chrome 瀏覽器工具欄中的擴充套件圖示。

擴充套件圖示

在上面的演示中,你可以看到我們的擴充套件圖示(釘住它)是灰色的,點選它時什麼也不會顯示,這是因為彈出頁面尚未建立。要建立彈出頁面,我們必須在 manifest 檔案中執行操作設定(action setting)。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"manifest_version": 3,
"name": "First Extension",
"version": "1.0.0",
"description": "My first extension",
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
+ "action": {
+ "default_icon": {
+ "16": "icon.png",
+ "24": "icon.png",
+ "32": "icon.png"
+ },
+ "default_title": "My Extension Action Title",
+ "default_popup": "popup.html"
+ }
}
{ "manifest_version": 3, "name": "First Extension", "version": "1.0.0", "description": "My first extension", "icons": { "16": "icon.png", "48": "icon.png", "128": "icon.png" }, + "action": { + "default_icon": { + "16": "icon.png", + "24": "icon.png", + "32": "icon.png" + }, + "default_title": "My Extension Action Title", + "default_popup": "popup.html" + } }
  {
"manifest_version": 3,
"name": "First Extension",
"version": "1.0.0",
"description": "My first extension",
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
+ "action": {
+    "default_icon": {
+     "16": "icon.png",
+        "24": "icon.png",
+        "32": "icon.png"
+      },
+      "default_title": "My Extension Action Title",
+  "default_popup": "popup.html"
+  }
}

傳遞給 default_popup 欄位的值就是點選擴充套件時將載入的 HTML 檔案。現在建立一個名為 popup.html 的新檔案。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
📦 chrome extension basics
┣ 🎨 icon.png
┣ 📄 manifest.json
┣ 📄 **popup.html**
📦 chrome extension basics ┣ 🎨 icon.png ┣ 📄 manifest.json ┣ 📄 **popup.html**
 📦 chrome extension basics
┣ 🎨 icon.png
┣ 📄 manifest.json
┣ 📄 **popup.html**
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>First Extension</title>
</head>
<body>
<h1>My First Extension</h1>
</body>
</html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>First Extension</title> </head> <body> <h1>My First Extension</h1> </body> </html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>First Extension</title>
</head>
<body>
<h1>My First Extension</h1>
</body>
</html>

現在我們可以在瀏覽器中檢視彈出頁面了。注:在更改 manifest 檔案時,必須始終重新載入擴充套件,如下面的演示所示。

重新載入擴充套件

現在,我們已經在彈出頁面上載入了 Html 檔案,可以使用 Javascript 使其互動,並使用 css 為其設計樣式。建立 popup.css 檔案,並將 popup.html 連線到該檔案。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>First Extension</title>
+ <link rel="stylesheet" href="popup.css">
......
</html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>First Extension</title> + <link rel="stylesheet" href="popup.css"> ...... </html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>First Extension</title>
+   <link rel="stylesheet" href="popup.css">
......
</html>
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
📦 chrome extension basics
┣ 🎨 icon.png
┣ 📄 manifest.json
┣ 📄 popup.html
┣ 📄 **popup.css**
📦 chrome extension basics ┣ 🎨 icon.png ┣ 📄 manifest.json ┣ 📄 popup.html ┣ 📄 **popup.css**
📦 chrome extension basics
┣ 🎨 icon.png
┣ 📄 manifest.json
┣ 📄 popup.html
┣ 📄 **popup.css**
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
body {
width: 400px;
height: 400px;
}
h1 {
color: blue;
}
body { width: 400px; height: 400px; } h1 { color: blue; }
body {
width: 400px;
height: 400px;
}
h1 {
color: blue;
}

用前面的程式碼設定了 popup.html 的樣式後,彈出文字現在是藍色的了。

現在,讓我們使用 Javascript 顯示當前時間,使彈出視窗更具互動性。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>First Extension</title>
<link rel="stylesheet" href="popup.css">
</head>
<body>
<h1>My First Extension</h1>
<h2 id="time"></h2>
</body>
<script src="popup.js"></script>
</html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>First Extension</title> <link rel="stylesheet" href="popup.css"> </head> <body> <h1>My First Extension</h1> <h2 id="time"></h2> </body> <script src="popup.js"></script> </html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>First Extension</title>
<link rel="stylesheet" href="popup.css">
</head>
<body>
<h1>My First Extension</h1>
<h2 id="time"></h2>
</body>
<script src="popup.js"></script>
</html>

現在建立 popup.js 檔案。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
📦 chrome extension basics
┣ 🎨 icon.png
┣ 📄 manifest.json
┣ 📄 popup.html
┣ 📄 popup.css
┣ 📄 **popup.js**
📦 chrome extension basics ┣ 🎨 icon.png ┣ 📄 manifest.json ┣ 📄 popup.html ┣ 📄 popup.css ┣ 📄 **popup.js**
📦 chrome extension basics
┣ 🎨 icon.png
┣ 📄 manifest.json
┣ 📄 popup.html
┣ 📄 popup.css
┣ 📄 **popup.js**
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const timeElement = document.getElementById('time')
const currentTime = new Date().toLocaleTimeString()
timeElement.textContent = `The time is: ${currentTime}`
const timeElement = document.getElementById('time') const currentTime = new Date().toLocaleTimeString() timeElement.textContent = `The time is: ${currentTime}`
const timeElement = document.getElementById('time')
const currentTime = new Date().toLocaleTimeString()
timeElement.textContent = `The time is: ${currentTime}`

現在,當你點選彈出視窗時,擴充套件程式就會顯示當前時間。

Chrome擴充套件demo

讓我們使用 chrome.action API 方法之一來增強擴充套件的互動性。讓我們在顯示文字 TIME 的彈出視窗上設定一個徽章。我們將使用 setBadgeText 方法。

 setBadgeText 方法

popup.js 中新增以下程式碼。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const timeElement = document.getElementById('time')
const currentTime = new Date().toLocaleTimeString()
timeElement.textContent = `The time is: ${currentTime}`
chrome.action.setBadgeText({
text: "TIME",
}, () => {
console.log('Finished setting badge text')
})
const timeElement = document.getElementById('time') const currentTime = new Date().toLocaleTimeString() timeElement.textContent = `The time is: ${currentTime}` chrome.action.setBadgeText({ text: "TIME", }, () => { console.log('Finished setting badge text') })
const timeElement = document.getElementById('time')
const currentTime = new Date().toLocaleTimeString()
timeElement.textContent = `The time is: ${currentTime}`
chrome.action.setBadgeText({
text: "TIME",
}, () => {
console.log('Finished setting badge text')
})

現在,我們的擴充套件有了一個顯示文字 TIME 的 icon,控制檯也會顯示該資訊。這樣就能正常工作了。

Dcidug9

Options 頁面

選項頁面是使用者與 Chrome 瀏覽器擴充套件互動的另一種方式,因此讓我們為擴充套件建立一個選項頁面。如果右鍵單擊擴充套件圖示,就會顯示 options,但由於尚未建立選項頁面,所以選項是禁用的。

要建立選項頁面,我們必須在 manifest.json 中新增 options 欄位。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"manifest_version": 3,
"name": "First Extension",
"version": "1.0.0",
"description": "My first extension",
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
"action": {
"default_icon": {
"16": "icon.png",
"24": "icon.png",
"32": "icon.png"
},
"default_title": "My Extension Action Title",
"default_popup": "popup.html"
},
+ "options_page": "options.html"
}
{ "manifest_version": 3, "name": "First Extension", "version": "1.0.0", "description": "My first extension", "icons": { "16": "icon.png", "48": "icon.png", "128": "icon.png" }, "action": { "default_icon": { "16": "icon.png", "24": "icon.png", "32": "icon.png" }, "default_title": "My Extension Action Title", "default_popup": "popup.html" }, + "options_page": "options.html" }
{
"manifest_version": 3,
"name": "First Extension",
"version": "1.0.0",
"description": "My first extension",
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
"action": {
"default_icon": {
"16": "icon.png",
"24": "icon.png",
"32": "icon.png"
},
"default_title": "My Extension Action Title",
"default_popup": "popup.html"
},
+  "options_page": "options.html"
}

現在建立一個 options.html 檔案,這將是我們的擴充套件選項頁面檔案。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
📦 chrome extension basics
┣ 🎨 icon.png
┣ 📄 manifest.json
┣ 📄 popup.html
┣ 📄 popup.css
┣ 📄 popup.js
┣ 📄 options.html
📦 chrome extension basics ┣ 🎨 icon.png ┣ 📄 manifest.json ┣ 📄 popup.html ┣ 📄 popup.css ┣ 📄 popup.js ┣ 📄 options.html
📦 chrome extension basics
┣ 🎨 icon.png
┣ 📄 manifest.json
┣ 📄 popup.html
┣ 📄 popup.css
┣ 📄 popup.js
┣ 📄 options.html
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Extension Options</title>
</head>
<body>
<h1>My Extension Options</h1>
</body>
</html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My Extension Options</title> </head> <body> <h1>My Extension Options</h1> </body> </html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Extension Options</title>
</head>
<body>
<h1>My Extension Options</h1>
</body>
</html>

現在,我們可以右鍵單擊圖示,選擇 “options” 選項,檢視擴充套件的選項頁面。

擴充套件的選項頁面

讓我們為 options 頁面設計風格並新增互動性。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="options.css">
<title>My Extension Options</title>
</head>
<body>
<h1>My Extension Options</h1>
<input id="name-input" type="text" placeholder="Enter your name!" />
<button id="save-btn">Save Options</button>
</body>
+ <script src="options.js"></script>
</html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="options.css"> <title>My Extension Options</title> </head> <body> <h1>My Extension Options</h1> <input id="name-input" type="text" placeholder="Enter your name!" /> <button id="save-btn">Save Options</button> </body> + <script src="options.js"></script> </html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="options.css">
<title>My Extension Options</title>
</head>
<body>
<h1>My Extension Options</h1>
<input id="name-input" type="text" placeholder="Enter your name!" />
<button id="save-btn">Save Options</button>
</body>
+ <script src="options.js"></script>
</html>

我們的專案目錄結構如下:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
📦 chrome extension basics
┣ 🎨 icon.png
┣ 📄 manifest.json
┣ 📄 popup.html
┣ 📄 popup.css
┣ 📄 popup.js
┣ 📄 options.html
┣ 📄 options.css
┣ 📄 options.js
📦 chrome extension basics ┣ 🎨 icon.png ┣ 📄 manifest.json ┣ 📄 popup.html ┣ 📄 popup.css ┣ 📄 popup.js ┣ 📄 options.html ┣ 📄 options.css ┣ 📄 options.js
📦 chrome extension basics
┣ 🎨 icon.png
┣ 📄 manifest.json
┣ 📄 popup.html
┣ 📄 popup.css
┣ 📄 popup.js
┣ 📄 options.html
┣ 📄 options.css
┣ 📄 options.js

options.css 中新增以下程式碼。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
h1 {
color: green;
}
h1 { color: green; }
h1 {
color: green;
}

options.js 中新增以下程式碼。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const nameInput = document.getElementById("name-input")
const saveBtn = document.getElementById("save-btn")
saveBtn.addEventListener("click", () => {
console.log(nameInput.value)
})
const nameInput = document.getElementById("name-input") const saveBtn = document.getElementById("save-btn") saveBtn.addEventListener("click", () => { console.log(nameInput.value) })
const nameInput = document.getElementById("name-input")
const saveBtn = document.getElementById("save-btn")
saveBtn.addEventListener("click", () => {
console.log(nameInput.value)
})

當點選 save Options 按鈕時,options.js 中的程式碼會獲取輸入框中的文字並登入到控制檯。

Chrome擴充套件選項頁面

Chrome 儲存 API

我們可以與使用者輸入選項頁面的資料進行互動,但目前還沒有辦法在選項頁面上儲存任何資料。我們需要一個儲存系統來儲存選項頁面上的資料,並在彈出頁面上訪問這些資料。為此,我們使用了 chrome 儲存 API

根據文件:

使用 chrome.storage API 來儲存、檢索和跟蹤使用者資料的更改。

儲存 API 有一些注意事項,但您可以認為它的工作原理與任何使用 Javascript 的基本本地儲存 API 類似。

在使用儲存 API 之前,有兩件事需要了解:

  1. 使用儲存 API 需要使用者許可(新增到 manifest 檔案中)。
  2. 主要有兩種儲存 API
    • chrome.storage.sync API
    • chrome.storage.local API兩者的主要區別在於,chrome.storage.sync API 會在不同的瀏覽器會話中同步所有 Chrome 瀏覽器儲存資料,而 chrome.storage.local 則只針對單個會話。不過,在處理使用者選項時,使用 chrome.storage.sync 是個不錯的做法,因為您希望資料能在不同的瀏覽器例項中儲存。

在使用儲存 API 之前,我們必須在 manifest.json 檔案的 permissions 欄位中新增儲存 API。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"manifest_version": 3,
"name": "First Extension",
"version": "1.0.0",
"description": "My first extension",
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
"action": {
"default_icon": {
"16": "icon.png",
"24": "icon.png",
"32": "icon.png"
},
"default_title": "My Extension Action Title",
"default_popup": "popup.html"
},
"options_page": "options.html",
+ "permissions": ["storage"]
}
{ "manifest_version": 3, "name": "First Extension", "version": "1.0.0", "description": "My first extension", "icons": { "16": "icon.png", "48": "icon.png", "128": "icon.png" }, "action": { "default_icon": { "16": "icon.png", "24": "icon.png", "32": "icon.png" }, "default_title": "My Extension Action Title", "default_popup": "popup.html" }, "options_page": "options.html", + "permissions": ["storage"] }
{
"manifest_version": 3,
"name": "First Extension",
"version": "1.0.0",
"description": "My first extension",
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
"action": {
"default_icon": {
"16": "icon.png",
"24": "icon.png",
"32": "icon.png"
},
"default_title": "My Extension Action Title",
"default_popup": "popup.html"
},
"options_page": "options.html",
+  "permissions": ["storage"]
}

然後在 options.js 中新增以下程式碼。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const nameInput = document.getElementById("name-input")
const saveBtn = document.getElementById("save-btn")
saveBtn.addEventListener("click", () => {
const name = nameInput.value;
chrome.storage.sync.set({
name,
}, () => {
console.log(`Name is set to ${name}`)
})
})
const nameInput = document.getElementById("name-input") const saveBtn = document.getElementById("save-btn") saveBtn.addEventListener("click", () => { const name = nameInput.value; chrome.storage.sync.set({ name, }, () => { console.log(`Name is set to ${name}`) }) })
const nameInput = document.getElementById("name-input")
const saveBtn = document.getElementById("save-btn")
saveBtn.addEventListener("click", () => {
const name = nameInput.value;
chrome.storage.sync.set({
name,
}, () => {
console.log(`Name is set to ${name}`)
})
})

在前面的程式碼中,我們通過 set 方法使用 Chrome 儲存 API 來儲存使用者輸入,該方法接受要儲存的值和回撥。

現在,如果你重新整理擴充套件,進入選項頁面並檢查控制檯,儲存的值就會被記錄下來。

進入選項頁面並檢查控制檯

如果我們重新整理頁面,你會發現即使我們在儲存中設定了輸入值,也沒有將 name 輸入的內部值更新為儲存的值。

為此,我們將使用 get 方法來獲取值(set 用於儲存值,get 用於獲取值)。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const nameInput = document.getElementById('name-input')
const saveBtn = document.getElementById('save-btn')
.....
chrome.storage.sync.get(['name'], (res) => {
nameInput.value = res.name ?? "???"
})
const nameInput = document.getElementById('name-input') const saveBtn = document.getElementById('save-btn') ..... chrome.storage.sync.get(['name'], (res) => { nameInput.value = res.name ?? "???" })
const nameInput = document.getElementById('name-input')
const saveBtn = document.getElementById('save-btn')
.....
chrome.storage.sync.get(['name'], (res) => {
nameInput.value = res.name ?? "???"
})

get 方法需要以下引數:

  • 一個包含要檢索的鍵值([name])的陣列(鍵值應與 set 方法中的鍵值一致)。
  • 回撥函式,其引數代表一個物件,其中包含最初用 set 方法儲存的值的鍵值繫結。

例如:假設儲存在 name 鍵中的值是 john

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
chrome.storage.sync.get(['name'], (res) => {
console.log(res)
})
//logs
{name: 'john'}
chrome.storage.sync.get(['name'], (res) => { console.log(res) }) //logs {name: 'john'}
    chrome.storage.sync.get(['name'], (res) => {
console.log(res)
})
//logs
{name: 'john'}

我們已經成功地在選項頁面上儲存並獲取了使用者輸入。讓我們在彈出頁面上顯示使用者輸入。在 popup.html 中新增。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
......
<body>
<h1>My First Extension</h1>
<h2 id="time"></h2>
+ <h2 id="name"></h2>
</body>
<script src="popup.js"></script>
</html>
...... <body> <h1>My First Extension</h1> <h2 id="time"></h2> + <h2 id="name"></h2> </body> <script src="popup.js"></script> </html>
......
<body>
<h1>My First Extension</h1>
<h2 id="time"></h2>
+    <h2 id="name"></h2>
</body>
<script src="popup.js"></script>
</html>

popup.js 中新增。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const timeElement = document.getElementById('time')
const nameElement = document.getElementById("name");
const currentTime = new Date().toLocaleTimeString()
timeElement.textContent = `The time is: ${currentTime}`
chrome.action.setBadgeText({
text: "TIME",
}, () => {
console.log('Finished setting badge text')
})
chrome.storage.sync.get(["name"], (res) => {
const name = res.name ?? "???"
nameElement.textContent = `Your name is: ${res.name}`
})
const timeElement = document.getElementById('time') const nameElement = document.getElementById("name"); const currentTime = new Date().toLocaleTimeString() timeElement.textContent = `The time is: ${currentTime}` chrome.action.setBadgeText({ text: "TIME", }, () => { console.log('Finished setting badge text') }) chrome.storage.sync.get(["name"], (res) => { const name = res.name ?? "???" nameElement.textContent = `Your name is: ${res.name}` })
    const timeElement = document.getElementById('time')
const nameElement = document.getElementById("name");
const currentTime = new Date().toLocaleTimeString()
timeElement.textContent = `The time is: ${currentTime}`
chrome.action.setBadgeText({
text: "TIME",
}, () => {
console.log('Finished setting badge text')
}) 
chrome.storage.sync.get(["name"], (res) => {
const name = res.name ?? "???"
nameElement.textContent = `Your name is: ${res.name}`
})

在前面的程式碼中,我們選擇了顯示儲存值的元素( nameElement ),從儲存中獲取值,並將其設定為所選元素的 textContent

現在,我們可以在彈出頁面的選項頁中檢視輸入的值。

彈出頁面的選項頁

後臺指令碼和 Service Workers

根據檔案

擴充套件是基於事件的程式,用於修改或增強 Chrome 瀏覽器的瀏覽體驗。事件是瀏覽器觸發器,例如導航到新頁面、刪除書籤或關閉標籤頁。擴充套件程式會在後臺指令碼中監控這些事件,然後根據指定指令做出反應。

後臺指令碼是一個 Javascript 檔案,在安裝 Chrome 瀏覽器擴充套件時在後臺執行。服務工作者在執行一段時間後總是處於空閒狀態;點選此處瞭解有關服務工作者的更多資訊。

讓我們為擴充套件實現後臺指令碼:

在我們的 manifest.json 檔案中新增 ” background” 欄位。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"manifest_version": 3,
"name": "First Extension",
"version": "1.0.0",
"description": "My first extension",
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
"action": {
"default_icon": {
"16": "icon.png",
"24": "icon.png",
"32": "icon.png"
},
"default_title": "My Extension Action Title",
"default_popup": "popup.html"
},
"options_page": "options.html",
"permissions": ["storage"],
"background": {
"service_worker": "lbackground.js"
}
}
{ "manifest_version": 3, "name": "First Extension", "version": "1.0.0", "description": "My first extension", "icons": { "16": "icon.png", "48": "icon.png", "128": "icon.png" }, "action": { "default_icon": { "16": "icon.png", "24": "icon.png", "32": "icon.png" }, "default_title": "My Extension Action Title", "default_popup": "popup.html" }, "options_page": "options.html", "permissions": ["storage"], "background": { "service_worker": "lbackground.js" } }
{
"manifest_version": 3,
"name": "First Extension",
"version": "1.0.0",
"description": "My first extension",
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
"action": {
"default_icon": {
"16": "icon.png",
"24": "icon.png",
"32": "icon.png"
},
"default_title": "My Extension Action Title",
"default_popup": "popup.html"
},
"options_page": "options.html",
"permissions": ["storage"],
"background": {
"service_worker": "lbackground.js"
}
}

建立 background.js 檔案

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
📦 chrome extension basics
┣ 🎨 icon.png
┣ 📄 manifest.json
┣ 📄 popup.html
┣ 📄 popup.css
┣ 📄 popup.js
┣ 📄 options.html
┣ 📄 options.css
┣ 📄 options.js
┣ 📄 background.js
📦 chrome extension basics ┣ 🎨 icon.png ┣ 📄 manifest.json ┣ 📄 popup.html ┣ 📄 popup.css ┣ 📄 popup.js ┣ 📄 options.html ┣ 📄 options.css ┣ 📄 options.js ┣ 📄 background.js
📦 chrome extension basics
┣ 🎨 icon.png
┣ 📄 manifest.json
┣ 📄 popup.html
┣ 📄 popup.css
┣ 📄 popup.js
┣ 📄 options.html
┣ 📄 options.css
┣ 📄 options.js
┣ 📄 background.js
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
consol.log("Hello from the background script!");
consol.log("Hello from the background script!");
    consol.log("Hello from the background script!");

進入擴充套件頁面並重新整理擴充套件

上面的演示顯示,新增後臺指令碼後,當你進入擴充套件頁面並重新整理擴充套件時,就會看到 inspect views:service worker 選項。點選 inspect 時,我們會看到它顯示了從 background.js 記錄到控制檯的資訊。

關於後臺指令碼,需要注意以下幾點:

  • 點選 service worker 選項時顯示的 devtools 環境與檢查彈出式頁面時看到的 devtools 環境並無不同,只是與我們的彈出式頁面相比,我們沒有 Elements 標籤,因為後臺指令碼全部是 Javascript(只有 Javascript 相關的 devtools 可用)。
  •  this 關鍵字並不指向後臺指令碼中的 window 物件,而是指向 ServiceWorkerGlobalScope 物件(這意味著它是一個服務工作者)。因此請注意,服務工作者的功能與 HTML 文件中的普通 Javascript 檔案不同。
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/// background.js
console.log(this)
// logs
> ServiceWorkerGlobalScope
/// background.js console.log(this) // logs > ServiceWorkerGlobalScope
/// background.js
console.log(this)
// logs
> ServiceWorkerGlobalScope

 background.js

現在,讓我們在後臺指令碼中設定一個計時器功能。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/// background.js
let time = 0
setInterval(() => {
time += 1
console.log(time)
}, 1000)
/// background.js let time = 0 setInterval(() => { time += 1 console.log(time) }, 1000)
/// background.js
let time = 0
setInterval(() => {
time +=  1
console.log(time)
}, 1000)

前面的程式碼通過 setInterval() 函式每秒增加一個 time 變數。

Chrome Alarms API

根據文件

使用 chrome.alarms API 可安排程式碼定期或在未來某個指定時間執行。

這意味著,即使服務 Worker 處於休眠狀態, chrome.alarms API 也允許程式碼在後臺指令碼中執行。

讓我們在 manifest 檔案中啟用此 API 的許可權。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/// manifest.json
......
"options_page": "options.html",
"permissions": ["storage", "alarms"]
"background": {
"service_worker": "background.js"
}
.....
/// manifest.json ...... "options_page": "options.html", "permissions": ["storage", "alarms"] "background": { "service_worker": "background.js" } .....
/// manifest.json
......
"options_page": "options.html",
"permissions": ["storage", "alarms"]  
"background": {
"service_worker": "background.js"   
}
.....

現在,讓我們在 background.js 中使用 chrome.alarms API 重新實現計時器功能。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
chrome.alarms.create({
periodInMinutes: 1 / 60,
})
chrome.alarms.onAlarm.addListener((alarm) => {
chrome.storage.local.get(["timer"], (res) => {
const time = res.timer ?? 0
chrome.storage.local.set({
timer: time + 1
})
console.log(time)
})
})
chrome.alarms.create({ periodInMinutes: 1 / 60, }) chrome.alarms.onAlarm.addListener((alarm) => { chrome.storage.local.get(["timer"], (res) => { const time = res.timer ?? 0 chrome.storage.local.set({ timer: time + 1 }) console.log(time) }) })
chrome.alarms.create({
periodInMinutes: 1 / 60, 
})
chrome.alarms.onAlarm.addListener((alarm) => {
chrome.storage.local.get(["timer"], (res) => {
const time = res.timer ?? 0
chrome.storage.local.set({
timer: time + 1
})
console.log(time)
})
})

前面的程式碼使用 chrome.alarms.create 方法通過 periodInMinutes 屬性建立了一個每秒觸發一次的警報。然後使用 onAlarm 方法監聽並響應警報。最後,我們使用 chrome.storage 設定和增加計時器,並將其記錄到控制檯。

Chrome Notifications API

根據文件

使用 chrome.notifications API 使用模板建立豐富的通知,並在系統托盤中向使用者顯示這些通知。

這意味著 chrome.notifications API 可用於為我們的擴充套件建立桌面通知。不過,需要注意的是,在 manifest V3 中,後臺指令碼是一個服務工作者。在 service Worker 中,有一個名為 ServiceWorkerRegistration 的物件。它有一個內建的顯示通知函式( ServiceWorkerRegistration.showNotification() ),可以在桌面上向使用者顯示通知。

現在,讓我們使用 API 在特定時間段過去後通知使用者。讓我們在 manifest 檔案中啟用此 API 的許可權。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/// manifest.json
......
"options_page": "options.html",
+ "permissions": ["storage", "alarms", "notifications"]
"background": {
"service_worker": "background.js"
}
.....
/// manifest.json ...... "options_page": "options.html", + "permissions": ["storage", "alarms", "notifications"] "background": { "service_worker": "background.js" } .....
/// manifest.json
......
"options_page": "options.html",
+ "permissions": ["storage", "alarms", "notifications"]  
"background": {
"service_worker": "background.js"   
}
.....

在 background.js

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
chrome.alarms.create({
periodInMinutes: 1 / 60,
})
chrome.alarms.onAlarm.addListener((alarm) => {
chrome.storage.local.get(["timer"], (res) => {
const time = res.timer ?? 0
chrome.storage.local.set({
timer: time + 1
})
if(time % 5 == 0) {
this.registration.showNotification('My first Extension', {
body: '1 second has passed',
icon: 'icon.png',
})
}
})
})
chrome.alarms.create({ periodInMinutes: 1 / 60, }) chrome.alarms.onAlarm.addListener((alarm) => { chrome.storage.local.get(["timer"], (res) => { const time = res.timer ?? 0 chrome.storage.local.set({ timer: time + 1 }) if(time % 5 == 0) { this.registration.showNotification('My first Extension', { body: '1 second has passed', icon: 'icon.png', }) } }) })
 chrome.alarms.create({
periodInMinutes: 1 / 60, 
})
chrome.alarms.onAlarm.addListener((alarm) => {
chrome.storage.local.get(["timer"], (res) => {
const time = res.timer ?? 0
chrome.storage.local.set({
timer: time + 1
})
if(time % 5 == 0) {
this.registration.showNotification('My first Extension', {
body: '1 second has passed',
icon: 'icon.png',
})
}
})
})

在前面的程式碼中,我們通過 serviceWorker 物件( this )訪問 showNotification() 函式。該函式接受兩個引數–一個表示通知標題的字串和一個包含不同通知配置選項的物件。在我們的例子中,通知標題是 “My first Extension“;配置物件包含 body 屬性(在通知正文中顯示的文字)和 icon(通知圖示)。我們的通知被包裹在一個 if 語句中,該語句每 5 秒觸發一次通知。

Chrome瀏覽器擴充套件通知

現在重新整理擴充套件頁面並等待 5 秒鐘,你就會在桌面上看到通知。

待續…

這就是本兩部分系列的第一部分。在下一部分中,我們將構建一個 Pomodoro 計時器擴充套件。

你可以從 GitHub 程式碼庫中下載本文的示例程式碼檔案。

同時,如果你想更深入地瞭解本文中的概念,請檢視下面的 “參考閱讀” 部分。

參考閱讀

評論留言