Chrome教程-在每个页面上运行脚本
欢迎开始您的第一个Chrome扩展开发实践,我们将创建一个扩展,使其能够向每个Chrome扩展和Chrome Web Store文档页面中插入一个新元素——预计阅读时间。
概述
本教程将引导您创建一个名为"阅读时间"的扩展,它能够在任何Chrome扩展和Chrome Web Store文档页面中显示预计阅读时间。
在这个教程中,您将学到以下概念:
- 扩展清单
- 扩展图标的尺寸要求
- 如何使用内容脚本来注入代码
- 如何使用匹配模式
- 扩展权限
开始之前准备
本教程假设您具有基本的网页开发经验。如果您需要,您可以先查看扩展开发的基础知识。
创建扩展
首先,在您的工作目录中创建一个名为reading-time
的文件夹,用于存储扩展的文件。如果您愿意,您也可以从GitHub上下载完整的源代码。
步骤1:添加扩展信息
清单JSON文件是扩展中唯一必需的文件,它包含了关于扩展的重要信息。在项目的根目录下创建一个名为manifest.json
的文件,并添加以下内容:
{
"manifest_version": 3,
"name": "阅读时间",
"version": "1.0",
"description": "向Chrome扩展和Chrome Web Store文档中添加阅读时间"
}
这些键包含了扩展的基本元数据。它们控制着扩展在扩展页面和Chrome Web Store中的显示方式。如果您想深入了解这些键的作用,可以查看清单文件概述页面。
有关清单的其他信息:
- 清单文件必须位于项目的根目录中。
- 唯一必需的键是
"manifest_version"
、"name"
和"version"
。 - 在开发期间,您可以使用注释(
//
)来进行注释,但在上传到Chrome Web Store之前,您需要删除这些注释。
步骤2:提供图标
但是,为什么我们需要图标呢?尽管在开发期间,图标是可选的,但是如果您计划将扩展发布到Chrome Web Store上,那么它们是必需的。这些图标还会显示在其他位置,比如扩展页面。
在您的项目中创建一个images
文件夹,并将图标文件放入其中。通常我们建议使用PNG格式的图标,但您也可以使用其他格式,除了SVG。
接下来,在清单文件中添加以下突出显示的代码来声明图标:
{
...
"icons": {
"16": "images/icon-16.png",
"32": "images/icon-32.png",
"48": "images/icon-48.png",
"128": "images/icon-128.png"
}
...
}
这些不同尺寸的图标将在以下地方显示:
图标尺寸 | 图标用途 |
---|---|
16x16 | 扩展页面上的网站图标和上下文菜单图标 |
32x32 | 通常在Windows电脑上显示 |
48x48 | 在扩展页面上显示 |
128x128 | 在安装时和Chrome Web Store中显示 |
步骤3:声明内容脚本
扩展可以运行内容脚本来读取和修改页面的内容。这些脚本被称为内容脚本,它们运行在隔离的环境中,这意味着它们可以修改页面的JavaScript环境而不与它们所在的主页面或其他扩展的内容脚本发生冲突。
在清单文件中添加以下代码,注册一个名为content.js
的内容脚本:
{
...
"content_scripts": [
{
"js": ["scripts/content.js"],
"matches": [
"https://developer.chrome.com/docs/extensions/*",
"https://developer.chrome.com/docs/webstore/*"
]
}
]
}
"matches"
字段可以包含一个或多个匹配模式,它们用于识别要向其注入内容脚本的网站。匹配模式由三个部分组成:<scheme>://<host><path>
。您可以使用通配符*
来进行模式匹配。
是否会显示权限警告?
在用户安装扩展时,浏览器会告知他们扩展的功能。内容脚本需要请求在匹配模式条件下的网站上运行的权限。
在这个例子中,用户将会看到以下权限警告:
步骤4:计算并插入阅读时间
内容脚本可以使用标准的文档对象模型(DOM)来读取和修改页面内容。扩展首先会检查页面中是否有<article>
元素,然后计算该元素中所有单词的数量,并创建一个段落来显示总阅读时间。
在一个名为scripts
的文件夹内创建一个名为content.js
的文件,并添加以下代码:
const article = document.querySelector("article");
// 如果选择器未匹配到任何内容,`document.querySelector`可能会返回 null。
if (article) {
const text = article.textContent;
const wordMatchRegExp = /[^\s]+/g; // 正则表达式
const words = text.matchAll(wordMatchRegExp);
// matchAll 返回一个迭代器,将其转换为数组以获取单词数
const wordCount = [...words].length;
const readingTime = Math.round(wordCount / 200);
const badge = document.createElement("p");
// 使用与文章标题中的发布信息相同的样式
badge.classList.add("color-secondary-text", "type--caption");
badge.textContent = `⏱️ ${readingTime} min read`;
// 对 API 参考文档的支持
const heading = article.querySelector("h1");
// 对带有日期的文章文档的支持
const date = article.querySelector("time")?.parentNode;
(date ?? heading).insertAdjacentElement("afterend", badge);
}
代码中的有趣JavaScript:
- 正则表达式用于只计算
<article>
元素内的单词。 insertAdjacentElement()
用于在元素之后插入阅读时间节点。classList
属性用于将CSS类添加到元素的类属性中。- 可选链用于访问可能为
undefined
或null
的对象属性。 - 空值合并用于在
<date>
为null
或undefined
时返回<heading>
。
测试是否有效
确保您的项目文件结构如下所示:
本地加载扩展
要在开发者模式下加载未打包的扩展,请按照扩展开发基础中的步骤进行操作。
打开一个扩展或Chrome Web Store文档
以下是您可以打开的一些页面,以查看每篇文章需要多长时间阅读。
页面应该会看起来像这样:
探索更多功能
根据您在本教程中学到的内容,您可以尝试实现以下功能之一:
- 在
manifest.json
中添加另一个匹配模式,以支持其他Chrome开发者页面,如Chrome DevTools或Workbox。 - 添加一个新的内容脚本,用于计算您喜欢的博客或文档站点的阅读时间。
提示:您可以使用DevTools来检查DOM元素。
继续前进吧!
恭喜您完成了这个教程 。您可以继续通过完成本系列中的其他教程来提升您的技能:
扩展 | 您将学到什么? |
---|---|
焦点模式 | 在当前页面上运行代码,单击扩展操作后执行。 |
选项卡管理器 | 创建一个管理浏览器选项卡的弹出窗口。 |