引言
大家好啊,我是前端拿破轮。
作为一个前端工程师,Chrome在我们的工作中扮演着重要作用。它不仅是前端的主要运行环境,而且是我们代码调试的重要工具,也是平时学习生活使用的重要软件。
在Chrome中有许多优秀的扩展,包括但不限于我们使用的React Devtools
,沉浸式翻译插件
等等。许多扩展极大地拓展了浏览器的能力边界,提高了我们工作和学校的效率。
所以笔者早有开发一个自己的插件的想法,苦于之前一直忙于学习和工作,没有合适的时间,最近忙里偷闲,决定抽出时间来进行这项工作。而且AI的时代浪潮也给浏览器的插件带来了新的生命力。所以笔者决定做一款浏览器端的AI助手插件。
本文属于Chrome插件开发专栏,会持续更新拿破轮的Chrome插件开发过程,欢迎各位读者订阅,希望对你有所帮助。如果还没有看过之前文章的读者,可以先阅读专栏中前面的文章。
专注模式Demo
需求目标:点击扩展程序工具栏图标,简化当前网页样式,进入专注模式
概述
本文将构建一个扩展程序,用于简化Chrome扩展程序和Chrome应用商店文档页面的样式,以便用户更轻松地阅读。
在本文中,我们将介绍如何执行以下操作:
- 将扩展程序
Service Worker
用作事件协调者 - 通过
activeTab
权限保护用户隐私 - 在用户点击扩展程序工具栏图标时运行代码
- 使用Scripting API插入和移除样式表
- 使用键盘快捷键执行代码
第 1 步:初始化扩展程序
这里为了方便,我们直接在本专栏之前文章的基础上进行修改,不再新建插件文件夹,没有看过之前文章的读者可以先看前面的文章。
扩展程序可以使用Service Worker
来监控浏览器事件。Service Worker
是一种特殊的JavaScript
环境,用于处理事件,并在不需要时终止。
首先,在manifest.json
中注册Service Worker
。
json
// manifest.json
{
...
"background": {
"service_worker": "background.js"
}
...
}
创建一个background.js
文件在根目录,并添加以下代码:
arduino
// background.js
chrome.runtime.onInstalled.addListener(() => {
chrome.action.setBadgeText({
text: 'OFF',
});
});
我们的Service Worker
将监听的第一个事件是runtime.onInstalled()
。借助此方法,扩展程序可以在安装时设置成初始状态或完成一些任务。扩展程序可以使用 Storage API
和 IndexedDB
存储应用状态。不过,在本例中,由于我们只处理两种状态,因此将使用操作图标本身来追踪扩展程序是处于"开启"还是"关闭"状态。
操作图标指的是工具栏扩展操作中的扩展图标
第 2 步:启用扩展程序操作
当我们在Chrome的扩展工具栏中点击扩展图标时,它将运行一些代码或者弹出一个弹窗。我们可以在manifest.json
中添加以下代码来声明扩展操作。
json
// manifest.json
{
...
"action": {
"default_icon": {
"16": "images/icon-16.png",
"32": "images/icon-32.png",
"48": "images/icon-48.png",
"128": "images/icon-128.png"
}
}
...
}
使用activeTab
权限保护用户隐私
activeTab
权限可授予扩展程序在有效标签页上执行临时代码的权限。它还允许访问当前标签页的敏感属性。
当用户调用扩展程序时,系统会启用此权限。在这种情况下,用户通过点击扩展程序图标来调用扩展程序。
用户的以下互动会启用
activeTab
权限
- 按键盘快捷键组合
- 选择上下文菜单项
- 接收
Omnibox
中的建议- 打开扩展程序弹出式窗口
借助activeTab
权限,用户可以有目的地选择在聚焦的标签页上运行扩展程序;这样一来,就可以保护用户的隐私,而且这种方式运行扩展程序也不会触发权限警告。
我们要想使用activeTab
权限,需要将其添加到manifest.json
的权限数组中。
json
{
...
"permissions": ["activeTab"],
...
}
第 3 步:跟踪当前标签页的状态
用户点击扩展程序后,该扩展程序会检查网址是否与文档页面匹配。接下来,它会检查当前标签页的状态并设置下一个状态。我们需要将以下代码添加到background.js
:
ini
const extensions = 'https://developer.chrome.com/docs/extensions';
const webstore = 'https://developer.chrome.com/docs/webstore';
chrome.action.onClicked.addListener(async (tab) => {
if (tab.url.startsWith(extensions) || tab.url.startsWith(webstore)) {
// 获取扩展图标,以检查扩展当前是否开启
const prevState = await chrome.action.getBadgeText({ tabId: tab.id });
// 写一个状态
const nextState = prevState === 'ON' ? 'OFF' : 'ON';
// 设置下一个状态
await chrome.action.setBadgeText({
tabId: tab.id,
text: nextState,
});
}
});
第 4 步:添加或移除样式表
创建一个名为focus-mode.css
的文件,并写入下面的代码
css
* {
display: none !important;
}
html,
body,
*:has(article),
article,
article * {
display: revert !important;
}
[role='navigation'] {
display: none !important;
}
article {
margin: auto;
max-width: 700px;
}
我们要想应用这个样式表,需要使用Scripting API来插入或移除样式表。
首先,我们需要再manifest.json
中声明script
权限。
json
{
...
"permission": ["activeTab", "scripting"],
...
}
最后,在background.js
中修改为如下代码。
php
// 等待扩展完全初始化
chrome.runtime.onInstalled.addListener(() => {
// 显式检查 chrome.action 是否存在
if (chrome.action) {
chrome.action.setBadgeText({ text: 'OFF' });
} else {
console.error('chrome.action API 不可用');
}
});
const extensions = 'https://developer.chrome.com/docs/extensions';
const webstore = 'https://developer.chrome.com/docs/webstore';
chrome.action.onClicked.addListener(async (tab) => {
if (tab.url.startsWith(extensions) || tab.url.startsWith(webstore)) {
// 获取扩展图标,以检查扩展当前是否开启
const prevState = await chrome.action.getBadgeText({ tabId: tab.id });
// 写一个状态
const nextState = prevState === 'ON' ? 'OFF' : 'ON';
// 设置下一个状态
await chrome.action.setBadgeText({
tabId: tab.id,
text: nextState,
});
if (nextState === 'ON') {
// 插入 CSS 文件
await chrome.scripting.insertCSS({
files: ['focus-mode.css'],
target: { tabId: tab.id },
});
} else if (nextState === 'OFF') {
// 移除 CSS 文件
await chrome.scripting.removeCSS({
files: ['focus-mode.css'],
target: {
tabId: tab.id,
},
});
}
}
});
Scripting API
不仅可以插入和移除 CSS,也可以使用scripting.executeScript()
来注入JavaScript
第 5 步:分配键盘快捷键
将commands
键添加到manifest.json
文件中。
json
{
...
"commands": {
"_execute_action": {
"suggested_key": {
"default": "Ctrl+B",
"mac": "Command+B"
}
}
}
...
}
_execute_action
按键会运行与action.onClicked
事件相同的代码,因此无需额外的代码。
测试效果
首先,打开以下任一页面:
我们以第一个页面为例,打开后如下图所示:

我们可以看到插件此时是OFF
状态,网页是正常模式。
我们点击插件 ,或者使用刚才设置的快捷键 Ctrl+B
(mac
是Command+B
),发现网页应用了我们的CSS样式文件,进入了专注模式,插件状态也面成了ON
。

总结
本文我们通过配置内容脚本,实现了在专注模式的Demo,知道了如何插入和移除样式表,并且进行了快捷键的配置。
本文属于Chrome插件开发专栏,会持续更新拿破轮的Chrome插件开发过程,欢迎各位读者订阅,希望对你有所帮助。
好了,这篇文章就到这里啦,如果对您有所帮助,欢迎点赞,收藏,分享👍👍👍。您的认可是我更新的最大动力。由于笔者水平有限,难免有疏漏不足之处,欢迎各位大佬评论区指正。
往期推荐✨✨✨
我是前端拿破轮,关注我,一起学习前端知识,我们下期见!