本文补充一下插件的界面组件。
1. 扩展图标(Action)
在 Chrome 工具栏上显示扩展图标,可单击触发弹出页面或执行操作。
通过 manifest.json 配置:
"action": {
"default_icon": "icon.png",
"default_popup": "popup.html",
"default_title": "My Extension"
}
支持 chrome.action API
控制图标状态,如动态更改图标或禁用。官方文档:👉点击这里
1.1 设置扩展图标
可以动态更改扩展图标:
chrome.action.setIcon({ path: "icons/new_icon.png" });
示例: 在 service-worker.js
中监听 chrome.runtime.onInstalled
事件,设置图标:
//service-worker.js
chrome.runtime.onInstalled.addListener(() => {
chrome.action.setIcon({ path: "icons/installed_icon.png" });
});
1.2 设置扩展标题
可以更改扩展图标的鼠标悬停提示:
chrome.action.setTitle({ title: "新的提示信息" });
示例: 当用户点击扩展图标时,更新标题:
//在用户点击操作图标时触发。请注意,如果操作包含弹出式窗口,此事件将不会触发。
chrome.action.onClicked.addListener(() => {
chrome.action.setTitle({ title: "你点击了扩展!" });
});
1.3 监听扩展图标点击事件
如果扩展未设置 default_popup
,点击扩展图标时可触发 onClicked
事件:
chrome.action.onClicked.addListener((tab) => {
console.log("扩展图标被点击,当前标签页:", tab);
});
注意:
如果 default_popup
被设置,则不会触发 onClicked
事件,必须清空 default_popup
才能使用此 API。
1.4 设置弹出页面
可以动态更改扩展图标点击后显示的弹出页面:
chrome.action.setPopup({ popup: "new_popup.html" });
示例:在特定条件下动态切换弹出页面:
chrome.runtime.onInstalled.addListener(() => {
chrome.storage.local.get("useNewPopup", (data) => {
let popup = data.useNewPopup ? "new_popup.html" : "popup.html";
chrome.action.setPopup({ popup });
});
});
1.5 禁用或启用扩展图标
禁用扩展图标:
chrome.action.disable();
启用扩展图标:
chrome.action.enable();
示例: 只有在特定网站上才启用扩展:
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (tab.url.includes("example")) {
chrome.action.enable(tabId);
} else {
chrome.action.disable(tabId);
}
});
1.6 动态修改扩展徽章
扩展图标支持 徽章(Badge),可以在图标上显示数字或文本。因为badge空间有限,所以只支持4个以下的字符(英文4个,中文2个)。
chrome.action.setBadgeText({ text: "5" }); // 显示“5”
chrome.action.setBadgeBackgroundColor({ color: "#FF0000" }); // 设置红色背景
示例: 监听消息,动态更新徽章:
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === "updateBadge") {
chrome.action.setBadgeText({ text: message.text });
}
});
1.7 注意事项
- 如果
default_popup
被设置,则onClicked
事件不会触发。 onClicked
事件的监听器必须在service-worker.js
中运行。
2. 右键菜单(Context Menus)
在 Chrome 扩展中,chrome.contextMenus
API允许开发者向 右键菜单(Context Menu) 添加自定义选项,增强扩展的交互功能。
官方文档:👉点击这里
chrome.contextMenus
主要用于向右键菜单添加扩展功能,适用于:
- 网页右键菜单(普通页面)
- 选中文本右键菜单
- 图片、视频、链接右键菜单
- 工具栏上的扩展右键菜单
- 开发者工具(DevTools)右键菜单
通过 manifest.json 配置:
"permissions": ["contextMenus"],
💡 关键点
contextMenus
权限 必须 声明,否则无法使用 API。- 由于是在
service-worker.js
运行的,必须在扩展安装时创建菜单。
2.1 创建右键菜单
在 service-worker.js
添加菜单项:
//service-worker.js
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create({
id: "sampleMenu",
title: "点击执行操作",
contexts: ["page"], // 仅在页面空白处右键时可见
});
});
参数解析 官方文档👉点击查看
参数 | 作用 |
---|---|
id | 菜单项唯一 ID |
title | 菜单显示的名称 |
contexts | 指定在哪些情况下显示菜单 |
documentUrlPatterns | 仅在匹配的 URL 下显示 |
targetUrlPatterns | 仅在匹配的链接或媒体 URL 下显示 |
parentId | 父菜单ID,创建子菜单使用 |
2.2 监听菜单点击事件
//service-worker.js
chrome.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "sampleMenu") {
console.log("右键菜单被点击", info, tab);
}
});
2.3 添加不同类型的右键菜单
2.3.1 针对选中文字
//service-worker.js
chrome.contextMenus.create({
id: "searchGoogle",
title: "在 Google 搜索:%s",
contexts: ["selection"] // 选中文本时显示
});
监听事件,打开 Google 搜索:
//service-worker.js
chrome.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "searchGoogle") {
let query = encodeURIComponent(info.selectionText);
let url = `https://www.google/search?q=${query}`;
chrome.tabs.create({ url });
}
});
2.3.2 针对图片
chrome.contextMenus.create({
id: "saveImage",
title: "保存图片",
contexts: ["image"]
});
监听点击事件:
chrome.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "saveImage") {
console.log("图片 URL:", info.srcUrl);
}
});
2.3.3 针对链接
chrome.contextMenus.create({
id: "copyLink",
title: "复制链接",
contexts: ["link"]
});
chrome.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "copyLink") {
navigator.clipboard.writeText(info.linkUrl).then(() => {
console.log("链接已复制:", info.linkUrl);
});
}
});
2.3.4 仅在特定网站生效
chrome.contextMenus.create({
id: "exampleOnly",
title: "仅在 example 显示",
contexts: ["page"],
documentUrlPatterns: ["*://*.example/*"] // 仅在 example 显示
});
2.3.5 创建子菜单
chrome.contextMenus.create({ id: "parent", title: "父菜单", contexts: ["page"] });
chrome.contextMenus.create({ id: "child1", title: "子菜单 1", parentId: "parent", contexts: ["page"] });
chrome.contextMenus.create({ id: "child2", title: "子菜单 2", parentId: "parent", contexts: ["page"] });
2.4 删除或更新菜单
删除菜单
chrome.contextMenus.remove("sampleMenu");
删除所有菜单
chrome.contextMenus.removeAll();
更新菜单
chrome.contextMenus.update("sampleMenu", {
title: "新菜单名称"
});
2.5 在 DevTools 添加右键菜单
如果你想在 开发者工具 中添加右键菜单:
//manifest.json
{
"devtools_page": "devtools.html"
}
在 devtools.js:
chrome.contextMenus.create({
id: "devToolsMenu",
title: "DevTools 右键菜单",
contexts: ["all"]
});
3. override(覆盖特定页面)
在 Chrome 扩展中,Override API 允许开发者替换特定的 Chrome 内置页面,如:
- 新标签页(New Tab Page, chrome://newtab/)
- 历史记录页面(History, chrome://history/)
- 书签管理页面(Bookmarks, chrome://bookmarks/)
注意点:
- 只能覆盖 newtab, history, bookmarks
- 必须在 manifest.json 配置 chrome_url_overrides
- 只能加载本地 HTML 文件,不能指向外部 URL
//manifest.json
{
"chrome_url_overrides": {
"newtab": "newtab.html",
"history": "history.html",
"bookmarks": "bookmarks.html"
}
}
4. option(插件选项界面)
Options Page 是 Chrome 扩展提供的设置界面,允许用户在扩展的管理界面(chrome://extensions/)中自定义扩展的行为和存储配置。
主要作用:
- 让用户修改扩展的设置
- 保存和读取数据(使用 chrome.storage)
- 提供交互式 UI
- 允许用户手动输入或选择配置项
所谓options页,就是插件的设置页面,有2个入口,一个是右键图标有一个“选项”菜单,还有一个在插件管理页面:
4.1 编写页面
//manifest.json
"options_page": "options/index.html",
注意事项:
- options_page 指定 options.html 作为选项页面。
- 必须声明 storage 权限,以便存储和读取用户的设置数据。
options/index.html
页面
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>chrome-devtools-demo</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="devtools.js"></script>
<script type="module" src="../popup/main.js"></script>
</body>
</html>
options.js
暂时可以先不写,先建一个文件就行
main.js
修改下:
import { createApp } from 'vue';
import Antd from 'ant-design-vue';
import App from './App.vue';
import Devtools from '../devtools/Devtools.vue';
import Options from '../options/Options.vue';
import 'ant-design-vue/dist/reset.css';
const app = createApp(App);
const devtools=createApp(Devtools);
const options=createApp(Options);
if (window.location.pathname === '/devtools/index.html') {
devtools.use(Antd).mount('#app')
}else if(window.location.pathname === '/options/index.html') {
options.use(Antd).mount('#app');
}else{
app.use(Antd).mount('#app');
}
4.2 处理用户输入(存储和读取设置)
使用 chrome.storage.sync.get()
加载已有的设置,如果没有,则使用默认值。
// 加载已有的设置
chrome.storage.sync.get(["settingA", "settingB"], (data) => {
a.value = data.settingA?? true; // 默认启用
b.value = data.settingB?? "#ff0000"; // 默认红色
});
使用 chrome.storage.sync.set()
保存用户设置。
chrome.storage
API 在上一章节已经讲解过用法,这边不再赘述。
4.3 在 Popup 页面中使用 Options Page
chrome.runtime.openOptionsPage()
-允许从 Popup
页面或 service-worker.js
脚本打开 options.html。
-避免用户手动进入 chrome://extensions/ 找到 Options。
5. 桌面通知
Chrome 扩展的 chrome.notifications
API 允许扩展程序向用户显示桌面通知,这些通知可以是:
- 文字通知
- 图像通知
- 进度条通知
- 按钮交互通知
主要作用:
- 向用户提供重要提醒(如下载完成、消息推送)。
- 结合 chrome.alarms 定时发送通知。
- 在后台服务 service worker 运行时向用户提供信息。
官方文档👉点击这里
在 manifest.json 中添加 notifications 权限:
"permissions": ["notifications"]
注意点:
notifications
是必需权限,否则无法使用chrome.notifications
API。- 必须在
service-worker.js
中运行通知,Popup
或Content Script
不能直接创建通知。
5.1 发送基本文本通知
//service-worker.js
chrome.notifications.create("test-notification", {
type: "basic",
iconUrl: chrome.runtime.getURL("icons/icon_16x16.png"),
title: "欢迎使用扩展",
message: "这是你的第一个桌面通知!",
priority: 2
});
代码解析
chrome.notifications.create(id, options, callback)
- id: 通知的唯一 ID(可省略,系统自动生成)。
- options:
- type: “basic”(基础通知)。
- iconUrl: 通知图标(必须是扩展内的 png)。
- title: 通知标题。
- message: 通知内容。
- priority: 通知优先级(0~2)。
Chrome 扩展可能会错误解析 iconUrl,所以你可以尝试用 chrome.runtime.getURL()
转换路径:
5.2 发送图片通知
chrome.notifications.create("image-notification", {
type: "image",
iconUrl: chrome.runtime.getURL("icons/icon_16x16.png"),
title: "图片通知示例",
message: "这是一个带图片的通知!",
imageUrl: chrome.runtime.getURL("icons/icon_16x16.png"),
priority: 1
});
5.3 发送带进度条的通知
let progress = 0;
let interval = setInterval(() => {
if (progress > 100) {
clearInterval(interval);
return;
}
chrome.notifications.create("progress-notification", {
type: "progress",
iconUrl: chrome.runtime.getURL("icons/icon_16x16.png"),
title: "下载进度",
message: `当前进度: ${progress}%`,
progress: progress
});
progress += 10;
}, 1000);
5.4 发送带交互按钮的通知
chrome.notifications.create("interactive-notification", {
type: "basic",
iconUrl: chrome.runtime.getURL("icons/icon_16x16.png"),
title: "是否接受?",
message: "点击按钮进行操作。",
buttons: [
{ title: "接受 ✅" },
{ title: "拒绝 ❌" }
]
});
监听按钮点击事件
chrome.notifications.onButtonClicked.addListener((notificationId, buttonIndex) => {
if (notificationId === "interactive-notification") {
if (buttonIndex === 0) {
console.log("用户点击了 '接受'");
} else {
console.log("用户点击了 '拒绝'");
}
}
});
5.5 监听通知点击事件
chrome.notifications.onClicked.addListener((notificationId) => {
if (notificationId === "test-notification") {
console.log("用户点击了通知!");
}
});
5.6 关闭通知
chrome.notifications.clear("test-notification", (wasCleared) => {
console.log(wasCleared ? "通知已关闭" : "通知不存在");
});
5.7 定时发送通知(结合 chrome.alarms)
chrome.alarms.create("reminder", { delayInMinutes: 1, periodInMinutes: 10 });
chrome.alarms.onAlarm.addListener((alarm) => {
if (alarm.name === "reminder") {
chrome.notifications.create({
type: "basic",
iconUrl: "icon.png",
title: "定时提醒",
message: "10 分钟过去了,该休息一下了!"
});
}
});
代码解析
chrome.alarms.create()
创建定时器:delayInMinutes
: 延迟 1 分钟后触发。periodInMinutes
: 每 10 分钟 触发一次。
chrome.alarms.onAlarm.addListener()
监听定时器,当时间到达时发送通知。
5.8 从 Popup 触发通知
popup.js
不能直接创建通知,只能向 service-worker.js
发送消息。
service-worker.js
监听 chrome.runtime.onMessage
并创建通知。
上一章节已经讲过消息通信,这边不再赘述。
6. devtools(开发者工具)
第一章已经讲过,这边不再赘述。
7. 国际化接口
插件根目录新建一个名为 _locales
的文件夹,再在下面新建一些语言的文件夹,如 en
、zh_CN
、zh_TW
,然后再在每个文件夹放入一个messages.json。例如:
_locales/en/messages.json
_locales/zh_CN/messages.json
同时必须在清单文件中设置default_locale。
"default_locale": "en"
_locales\en\messages.json内容:
{
"name": {
"message": "chrome-extensions-demo",
"description": "name"
}
}
_locales\zh_CN\messages.json内容:
{
"name": {
"message": "谷歌插件示例",
"description": "name"
}
}
在manifest.json和CSS文件中通过__MSG_messagename__引入,如:
"name": "__MSG_name__",
JS则直接通过 chrome.i18n.getMessage("name")
。
官方文档👉点击这里
补充说明:chrome.i18n.getMessage("messageName", [substitutions])
messageName
: 要获取的消息的名称,它对应于在_locales
目录下messages.json
文件中的键。substitutions
(可选): 替换字符串数组,用于替换messages.json
中的占位符。
假设你有一个 _locales/zh_CN/messages.json 文件,内容如下:
//第一种写法
{
"click_here": {
"message": "点击这里:$1 和 $2"
}
}
//第二种写法
{
"name": {
"message": "谷歌插件示例",
"description": "name"
},
"click_here": {
"message": "点击这里:$string1$ 和 $string2$",
"placeholders": {
"string1": {
"content": "$1",
"example": "描述使用示例"
},
"string2": {
"content": "$2",
"example": "描述使用示例"
}
}
}
}
在这个例子中,click_here 是消息的名称,而 $1 和 $2 是占位符,用来替换动态内容。
然后在你的 JavaScript 代码中,你可以使用 chrome.i18n.getMessage 来获取并替换这些占位符:
let message = chrome.i18n.getMessage("click_here", ["字符串1", "字符串2"]);
console.log(message);
发布评论