欢迎开始您的第一个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>。您可以使用通配符*来进行模式匹配。

是否会显示权限警告?

在用户安装扩展时,浏览器会告知他们扩展的功能。内容脚本需要请求在匹配模式条件下的网站上运行的权限。

在这个例子中,用户将会看到以下权限警告:

1.jpg

步骤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类添加到元素的类属性中。
  • 可选链用于访问可能为undefinednull的对象属性。
  • 空值合并用于在<date>nullundefined时返回<heading>

测试是否有效

确保您的项目文件结构如下所示:

2.jpg

本地加载扩展

要在开发者模式下加载未打包的扩展,请按照扩展开发基础中的步骤进行操作。

打开一个扩展或Chrome Web Store文档

以下是您可以打开的一些页面,以查看每篇文章需要多长时间阅读。

页面应该会看起来像这样:

3.jpg

探索更多功能

根据您在本教程中学到的内容,您可以尝试实现以下功能之一:

  • manifest.json中添加另一个匹配模式,以支持其他Chrome开发者页面,如Chrome DevTools或Workbox。
  • 添加一个新的内容脚本,用于计算您喜欢的博客或文档站点的阅读时间。

提示:您可以使用DevTools来检查DOM元素。

继续前进吧!

恭喜您完成了这个教程 。您可以继续通过完成本系列中的其他教程来提升您的技能:

扩展您将学到什么?
焦点模式在当前页面上运行代码,单击扩展操作后执行。
选项卡管理器创建一个管理浏览器选项卡的弹出窗口。

标签: chrome, Chrome开发, Chrome语法, Chrome脚本, Chrome教程, Chrome入门, Chrome入门教程, Chrome进阶, Chrome宝典, Chrome学习, Chrome指南, Chrome插件, Chrome脚本开发, Chrome插件开发, Chrome基础, Chrome入门基础