
欢迎阅读 Chrome 浏览器扩展开发新手入门!本系列的主要目的是介绍 Chrome 扩展的基本概念以及如何创建扩展。在本系列结束时,你将使用 *** 一个 Pomodoro 计时器扩展。
要创建任何 ,我们都必须依赖 。无论是 Chrome API 还是在 Chrome 网站上发布,这都是与扩展相关的唯一真相来源。Chrome API 是特殊的 Javascript 函数或特殊的 manifest 文件(稍后详述)字段,允许我们通过 Chrome 扩展与 Chrome 浏览器进行交互。它们由 chrome 关键字和 API 名称 chrome.[API name]表示。

manifest 文件是每个扩展的核心。通过它,你可以告诉 *** 浏览器你的 Chrome 浏览器扩展应该做什么,以及扩展由哪些 Javascript、Html 和 Css 文件组成。
根据 Chrome 浏览器开发人员的:
扩展的 manifest 是唯一必需的文件,它必须有一个特定的文件名: manifest.json。它还必须位于扩展的根目录中。清单记录了重要的元数据、定义了资源、声明了权限,并确定了要在后台和页面上运行的文件。
这意味着 manifest 文件是一个 (Javascript 对象符号)格式的文件。
让我们来看一些代码示例:
从本文的 GitHub 代码库中下载代码,在中打开 chrome extension basics 文件夹。它应该是这样的
Chrome-Extension-Series ┣ icon.png
创建新的 manifest.json 文件
chrome extension basics ┣ icon.png ┣ **manifest.json**
添加新的 manifest.json 文件后,在其中添加以下代码。
{
"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 扩展了。

manifest.json 文件的 chrome extension basics 文件夹按照上述步骤操作后,你的 Chrome 浏览器扩展应该已经加载到浏览器中了。如果我们查看 Chrome 浏览器的扩展页面,就会看到已加载的扩展。

点击了解有关 manifest 文件的更多信息
既然我们已经加载了基本扩展,那么就来添加一些交互功能吧。popup 是每个扩展都有的交互元素;当你点击扩展图标时,它就会出现在工具栏上。
根据文档:
使用 chrome.action API 控制 Google Chrome 浏览器工具栏中的扩展图标。

在上面的演示中,你可以看到我们的扩展图标(钉住它)是灰色的,点击它时什么也不会显示,这是因为弹出页面尚未创建。要创建弹出页面,我们必须在 manifest 文件中执行操作设置()。
{
"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 的新文件。
chrome extension basics ┣ icon.png ┣ manifest.json ┣ **popup.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 连接到该文件。
<!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>
chrome extension basics ┣ icon.png ┣ manifest.json ┣ popup.html ┣ **popup.css**
body {
width: 400px;
height: 400px;
}
h1 {
color: blue;
}
用前面的代码设置了 popup.html 的样式后,弹出文字现在是蓝色的了。
现在,让我们使用 Javascript 显示当前时间,使弹出窗口更具互动性。
<!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 文件。
chrome extension basics ┣ icon.png ┣ manifest.json ┣ popup.html ┣ popup.css ┣ **popup.js**
const timeElement = document.getElementById('time')
const currentTime = new Date().toLocaleTimeString()
timeElement.textContent = `The time is: ${currentTime}`
现在,当你点击弹出窗口时,扩展程序就会显示当前时间。

让我们使用 chrome.action API *** 之一来增强扩展的交互性。让我们在显示文本 TIME 的弹出窗口上设置一个徽章。我们将使用 setBadgeText *** 。

在 popup.js 中添加以下代码。
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,控制台也会显示该信息。这样就能正常工作了。

选项页面是用户与 Chrome 浏览器扩展互动的另一种方式,因此让我们为扩展创建一个选项页面。如果右键单击扩展图标,就会显示 options,但由于尚未创建选项页面,所以选项是禁用的。
要创建选项页面,我们必须在 manifest.json 中添加 options 字段。
{
"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 文件,这将是我们的扩展选项页面文件。
chrome extension basics ┣ icon.png ┣ manifest.json ┣ popup.html ┣ popup.css ┣ popup.js ┣ options.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 页面设计风格并添加互动性。
<!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>
我们的项目目录结构如下:
chrome extension basics ┣ icon.png ┣ manifest.json ┣ popup.html ┣ popup.css ┣ popup.js ┣ options.html ┣ options.css ┣ options.js
在 options.css 中添加以下代码。
h1 {
color: green;
}
在 options.js 中添加以下代码。
const nameInput = document.getElementById("name-input")
const saveBtn = document.getElementById("save-btn")
saveBtn.addEventListener("click", () => {
console.log(nameInput.value)
})
当点击 save Options 按钮时,options.js 中的代码会获取输入框中的文本并登录到控制台。

我们可以与用户输入选项页面的数据进行交互,但目前还没有办法在选项页面上存储任何数据。我们需要一个存储系统来存储选项页面上的数据,并在弹出页面 *** 问这些数据。为此,我们使用了 。
根据文档:
使用 chrome.storage API 来存储、检索和跟踪用户数据的更改。
存储 API 有一些注意事项,但您可以认为它的工作原理与任何使用 Javascript 的基本本地存储 API 类似。
在使用存储 API 之前,有两件事需要了解:
chrome.storage.sync APIchrome.storage.local API两者的主要区别在于,chrome.storage.sync API 会在不同的浏览器会话中同步所有 Chrome 浏览器存储数据,而 chrome.storage.local 则只针对单个会话。不过,在处理用户选项时,使用 chrome.storage.sync 是个不错的做法,因为您希望数据能在不同的浏览器实例中保存。在使用存储 API 之前,我们必须在 manifest.json 文件的 permissions 字段中添加存储 API。
{
"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 中添加以下代码。
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 用于获取值)。
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
chrome.storage.sync.get(['name'], (res) => {
console.log(res)
})
//logs
{name: 'john'}
我们已经成功地在选项页面上存储并获取了用户输入。让我们在弹出页面上显示用户输入。在 popup.html 中添加。
...... <body> <h1>My First Extension</h1> <h2 id="time"></h2> + <h2 id="name"></h2> </body> <script src="popup.js"></script> </html>
在 popup.js 中添加。
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 。
现在,我们可以在弹出页面的选项页中查看输入的值。

根据:
扩展是基于事件的程序,用于修改或增强 Chrome 浏览器的浏览体验。事件是浏览器触发器,例如导航到新页面、删除书签或关闭标签页。扩展程序会在后台脚本中监控这些事件,然后根据指定指令做出反应。
后台脚本是一个 Javascript 文件,在安装 Chrome 浏览器扩展时在后台运行。服务工作者在运行一段时间后总是处于空闲状态;了解有关服务工作者的更多信息。
让我们为扩展实现后台脚本:
在我们的 manifest.json 文件中添加 ” background” 字段。
{
"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 文件
chrome extension basics ┣ icon.png ┣ manifest.json ┣ popup.html ┣ popup.css ┣ popup.js ┣ options.html ┣ options.css ┣ options.js ┣ background.js
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 文件不同。/// background.js console.log(this) // logs > ServiceWorkerGlobalScope

现在,让我们在后台脚本中设置一个计时器功能。
/// background.js
let time = 0
setInterval(() => {
time += 1
console.log(time)
}, 1000)
前面的代码通过 setInterval() 函数每秒增加一个 time 变量。
根据
使用 chrome.alarms API 可安排代码定期或在未来某个指定时间运行。
这意味着,即使服务 Worker 处于休眠状态, chrome.alarms API 也允许代码在后台脚本中运行。
让我们在 manifest 文件中启用此 API 的权限。
/// manifest.json
......
"options_page": "options.html",
"permissions": ["storage", "alarms"]
"background": {
"service_worker": "background.js"
}
.....
现在,让我们在 background.js 中使用 chrome.alarms API 重新实现计时器功能。
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 可用于为我们的扩展创建桌面通知。不过,需要注意的是,在 中,后台脚本是一个服务工作者。在 service Worker 中,有一个名为 的对象。它有一个内置的显示通知函数(),可以在桌面上向用户显示通知。
现在,让我们使用 API 在特定时间段过去后通知用户。让我们在 manifest 文件中启用此 API 的权限。
/// manifest.json
......
"options_page": "options.html",
+ "permissions": ["storage", "alarms", "notifications"]
"background": {
"service_worker": "background.js"
}
.....
在 background.js
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 秒触发一次通知。

现在刷新扩展页面并等待 5 秒钟,你就会在桌面上看到通知。
这就是本两部分系列的之一部分。在下一部分中,我们将构建一个 Pomodoro 计时器扩展。
你可以从 中下载本文的示例代码文件。
同时,如果你想更深入地了解本文中的概念,请查看下面的 “参考阅读” 部分。
不久前,PHP 8.0大张旗鼓地发布了。它带来了许多新特性、性能增强和变化——其中最令人兴奋的是新的JIT编译器。 技术世界总是在向前发展,PHP也是如此。 ,包含了几个令人兴奋的特性。它定于今年晚些时候于2021年11月25日发布。 在本文中,我们将详细介绍PHP 8.1将带来哪些新的东...
宝塔面板现在已经成为国内许多站长必备的服务器管理必备工具。相比直接使用SSH+FTP来管理服务器,宝塔面板可以提供可视化管理,包括文件管理、数据库管理、数据备份、SSL配置等等。 如果你希望更简单高效地管理您的网站及服务器,宝塔面板是不错的选择。下面是一些宝塔面板安装及常见问题:...
Linux面板环境安装,主要支持LNMP和LAMP、Tomcat、node.js。不过对于大部分站长来说,主要是LNMP和LAMP两个环境的安装。 LNMP和LAMP两个环境的最大区别是,前者采用Nginx作为Web服务器,后者则采用Apache作为Web服务器。(选择哪个作为您的Web服务器,可...
使用宝塔面板,您可以快速地创建一个FTP管理账户,对网站文件进行管理。但有必要提醒大家的是,使用FTP远不如使用SFTP安全,你可以查看文章“”进一步了解两者之间的差异。 此外,宝塔面板的文件管理模块其实已经能够满足站长的大部分文件管理需求。当然,如果你非得要使用FTP管理服务器文件,可以参照以下...
宝塔面板设置主要涉及的是宝塔控制后台自身的参数,包括诸如面板的开关、自动更新及SSL、面板端口设置等。虽然这部分不涉及服务器自身的管理,但对宝塔面板的设置也有其重要。 特别是面板端口、安全入口及面板密码等涉及安全的参数设置。 启动和关闭面板 如果你长时间无需使用到宝塔面板,可以考虑...
宝塔面板的计划任务,主要用于安排和管理需要定时执行的任务,如备份、内存清理等。其实对于大部分站长来说,主要使用该板块的备份网站、备份数据库及释放内存的三个定时任务计划。 Shell脚本的添加 输入任务名称,选择执行周期,输入执行的脚本内容。 注意事项: 输入脚本内容...