构建您的第一个标签页管理器。
概览
此教程会构建一个标签页管理器,用于整理 Chrome 扩展程序和 Chrome 应用商店的文档标签页。
在本指南中,我们将介绍如何执行以下操作:
- 使用 Action API 创建扩展程序弹出式窗口。
- 使用 Tabs API 查询特定标签页。
- 通过缩小主机权限保护用户隐私。
- 更改标签页的焦点。
- 将标签页移至同一窗口并分组。
- 使用 TabGroups API 重命名标签页组。
前期准备
本指南假定您具备基本的 Web 开发经验。建议您查看 Hello World,了解有关扩展程序开发工作流的简介。
构建扩展程序
首先,创建一个名为 tabs-manager
的新目录来存放扩展程序的文件。如果您愿意,可以在 GitHub 上下载完整的源代码。
第 1 步:添加扩展程序数据和图标
创建一个名为 manifest.json
的文件,并添加以下代码:
{
"manifest_version": 3,
"name": "Tab Manager for Chrome Dev Docs",
"version": "1.0",
"icons": {
"16": "images/icon-16.png",
"32": "images/icon-32.png",
"48": "images/icon-48.png",
"128": "images/icon-128.png"
}
}
如需详细了解这些清单键,请查看“阅读时间”教程,该教程详细介绍了该扩展程序的元数据和图标。
创建一个 images
文件夹,然后将图标下载到其中。
第 2 步:创建弹出式窗口并设置样式
Action API 可控制扩展程序操作(工具栏图标)。当用户点击扩展程序操作时,它会运行一些代码或打开一个弹出式窗口,如下所示。首先,在 manifest.json
中声明弹出式窗口:
{
"action": {
"default_popup": "popup.html"
}
}
弹出式窗口与网页类似,但有一点例外:它无法运行内嵌 JavaScript。创建一个 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" />
<link rel="stylesheet" href="./popup.css" />
</head>
<body>
<template id="li_template">
<li>
<a>
<h3 class="title">Tab Title</h3>
<p class="pathname">Tab Pathname</p>
</a>
</li>
</template>
<h1>Google Dev Docs</h1>
<button>Group Tabs</button>
<ul></ul>
<script src="./popup.js" type="module"></script>
</body>
</html>
接下来,您将设置弹出式窗口的样式。创建一个 popup.css
文件,并添加以下代码。
body {
width: 20rem;
}
ul {
list-style-type: none;
padding-inline-start: 0;
margin: 1rem 0;
}
li {
padding: 0.25rem;
}
li:nth-child(odd) {
background: #80808030;
}
li:nth-child(even) {
background: #ffffff;
}
h3,
p {
margin: 0;
}
第 3 步:管理标签页
通过 Tabs API,扩展程序可以在浏览器中创建、查询、修改和重新排列标签页。
请求权限
Tabs API 中的许多方法无需请求任何权限即可使用。不过,我们需要访问标签页的 title
和 URL
;这些敏感属性需要权限。我们可以请求 "tabs"
权限,但这样做会获得对所有标签页的敏感属性的访问权限。由于我们只管理特定网站的标签页,因此会请求较小的主机权限。
缩小主机权限范围可让我们向特定网站授予更高的权限,从而保护用户隐私。这将授予对 title
和 URL
属性的访问权限以及其他功能。将突出显示的代码添加到 manifest.json
文件中:
{
"host_permissions": [
"https://developer.chrome.com/*"
]
}
💡? 标签页权限和主机权限之间的主要区别是什么?
"tabs"
权限和主机权限都有缺点。
"tabs"
权限允许扩展程序读取所有标签页上的敏感数据。随着时间的推移,此信息可能会被用于收集用户的浏览记录。因此,如果您请求此权限,Chrome 将在安装时显示以下警告消息:
借助主机权限,扩展程序可以读取和查询匹配标签页的敏感属性,还可在这些标签页上注入脚本。用户在安装时会看到以下警告消息:
此类警告可能会让用户感到担忧。为了获得更好的入门体验,我们建议您实现可选权限。
查询标签页
您可以使用 tabs.query()
方法从特定网址检索标签页。创建一个 popup.js
文件并添加以下代码:
const tabs = await chrome.tabs.query({
url: [
"https://developer.chrome.com/docs/webstore/*",
"https://developer.chrome.com/docs/extensions/*",
]
});
💡? 我可以直接在弹出式窗口中使用 Chrome API 吗?
弹出式窗口和其他扩展程序页面可以调用任何 Chrome API,因为它们是通过 Chrome 架构提供的。例如 chrome-extension://EXTENSION_ID/popup.html
。
将焦点移至某个标签页
首先,该扩展程序会按字母顺序对标签页名称(所含 HTML 网页的标题)进行排序。然后,当用户点击某个列表项时,它会使用 tabs.update()
将焦点置于该标签页上,并使用 windows.update()
将窗口置于最前面。将以下代码添加到 popup.js
文件中:
...
const collator = new Intl.Collator();
tabs.sort((a, b) => collator.compare(a.title, b.title));
const template = document.getElementById("li_template");
const elements = new Set();
for (const tab of tabs) {
const element = template.content.firstElementChild.cloneNode(true);
const title = tab.title.split("-")[0].trim();
const pathname = new URL(tab.url).pathname.slice("/docs".length);
element.querySelector(".title").textContent = title;
element.querySelector(".pathname").textContent = pathname;
element.querySelector("a").addEventListener("click", async () => {
// need to focus window as well as the active tab
await chrome.tabs.update(tab.id, { active: true });
await chrome.windows.update(tab.windowId, { focused: true });
});
elements.add(element);
}
document.querySelector("ul").append(...elements);
...
💡? 这段代码中使用了有趣的 JavaScript
- 用于根据用户首选语言对标签页数组进行排序的整理器。
- 模板标记用于定义可克隆的 HTML 元素(而不是使用
document.createElement()
来创建每一项)。 - 用于创建和解析网址的网址构造函数。
- Spread 语法用于将一组元素转换为
append()
调用中的参数。
为标签页分组
TabGroups API 允许扩展程序为组命名并选择背景颜色。通过添加突出显示的代码,向清单中添加 "tabGroups"
权限:
{
"permissions": [
"tabGroups"
]
}
在 popup.js
中,添加以下代码以创建按钮,该按钮将使用 tabs.group()
对所有标签页进行分组,并将其移动到当前窗口中。
const button = document.querySelector("button");
button.addEventListener("click", async () => {
const tabIds = tabs.map(({ id }) => id);
if (tabIds.length) {
const group = await chrome.tabs.group({ tabIds });
await chrome.tabGroups.update(group, { title: "DOCS" });
}
});
测试它是否正常运行
验证项目的文件结构是否与以下目录树匹配:
在本地加载扩展程序
如需在开发者模式下加载已解压的扩展程序,请按照 Hello World 中的步骤操作。
打开一些文档页面
在不同窗口中打开以下文档:
点击弹出式窗口。显示的内容应如下所示:
点击“分组标签页”按钮。显示的内容应如下所示:
🎯? 有望改进的方面
根据今天学到的知识,尝试实现以下任何操作:
- 自定义弹出式样式表。
- 更改标签页分组的颜色和标题。
- 管理其他文档网站的标签页。
- 添加了对对已分组的标签页取消分组的支持。
继续努力!
恭喜您学完了本教程 🎉?。请继续学习本系列中的其他教程,进一步提升您的技能:
扩展程序 | 学习内容 |
---|---|
阅读时间 | 在每个网页上自动插入元素。 |
专注模式 | 点击扩展程序操作后在当前页面上运行代码。 |
继续探索
我们希望您喜欢这个 Chrome 扩展程序的构建过程,并且很高兴能够继续您的 Chrome 开发学习之旅。我们建议您学习以下学习路线:
- 开发者指南还有数十个额外链接,这些链接指向与创建高级扩展程序相关的文档片段。
- 扩展程序可以访问除开放 Web 上提供的 API 之外的强大 API。 Chrome API 文档详细介绍了各个 API。