Chrome 扩展程序:更改网页
示例
关于内容脚本
让我们开始编码吧!
仓库
在这篇文章中,我将重点介绍内容脚本以及如何使用它们来更改网页。
我们将探讨的主要概念是:
- 使用内容脚本对网页进行更改。
- 附加 HTML
- 添加新样式
- 在后台脚本和内容脚本之间发送消息
- 从内容脚本访问我们的扩展资源
目录
示例
为了本文的示例,我将继续在初始示例扩展中添加功能:我们将使用内容脚本在当前活动页面的右下角显示通知。
我们还将依赖本系列之前学到的知识:一个命令将触发通知,并由我们的后台脚本处理。最后,后台脚本将向内容脚本发送消息,以激活在屏幕右下角显示页面标题的通知:
关于内容脚本
- 内容脚本是在与用户访问的网页相同的上下文中运行的文件。
- 它们与页面的 DOM 共享访问权限。
- 在这些脚本中,我们可以使用JavaScript访问网页元素、读取其内容并进行更改。我们还可以使用CSS为网页添加新的样式。
- 它们允许您从页面中提取信息并将其发送给其他脚本或从我们的扩展程序接收消息。
- 最后,内容脚本可以访问一些 chrome API,这使我们能够执行诸如获取当前 URL、访问扩展的存储等操作。
让我们开始编码吧!
1. 创建新命令
在本系列的上一篇文章中,我们向示例扩展添加了两个命令。现在我们要添加第三个命令。
为此,首先,我们将在manifest.json
文件中定义该命令及其建议的快捷键:
{
"manifest_version": 2,
"name": "Acho, where are we?",
// ...
"commands": {
"bark": {
"suggested_key": {
"default": "Alt+Shift+3"
},
"description": "Makes Acho bark the title at the bottom right of the current page."
},
// .... Other commands
}
}
现在,我们需要通过监听事件来处理命令onCommand
。这应该在后台脚本中完成:
// background.js
chrome.commands.onCommand.addListener(function (command) {
switch (command) {
case 'bark':
barkTitle();
break;
default:
console.log(`Command ${command} not found`);
}
});
function barkTitle() {
const query = { active: true, currentWindow: true };
chrome.tabs.query(query, (tabs) => {
chrome.tabs.sendMessage(tabs[0].id, {
tabTitle: tabs[0].title
});
});
}
因此,一旦bark
命令执行,我们将发送一条消息,指示当前活动选项卡的标题。
现在我们的内容脚本需要监听该消息并显示通知。
关于消息:内容脚本不是在扩展程序的上下文中运行,而是在网页的上下文中运行。它们需要一种与扩展程序通信的方式。我们可以使用消息来实现这一点。
- 要向内容脚本发送消息,请使用
chrome.tabs.sendMessage
并指定TabId
。该消息将发送到该选项卡中运行的内容脚本。- 要从内容脚本发送消息,请使用
chrome.runtime.sendMessage
。
2. 注册内容脚本
要创建内容脚本,我们需要做的第一件事是(是的,你猜对了!)将其添加到manifest.json
文件中:
{
"manifest_version": 2,
"name": "Acho, where are we?",
// ...
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"],
"css": ["content.css"]
}
],
"web_accessible_resources": [
"images/icon32.png"
],
}
content_scripts
:内容脚本数组。我们可以注册多个脚本,每个脚本都有不同的配置。matches
:一个字符串表达式数组,用于指定此特定内容脚本将被注入到哪些页面。您可以使用"matches": ["<all_urls>"]
它将其注入到任何 URL 中。js
:JavaScript 文件数组。这些文件将处理内容脚本的逻辑。css
:CSS 文件数组。在本例中,我们将使用 CSS 文件来定义通知样式。web_accessible_resources
:我们需要从内容脚本访问的资源列表。由于内容脚本与扩展程序的运行上下文不同,因此我们想要访问的任何扩展程序资源都必须在此处明确提供。
3. 显示通知
让我们首先添加逻辑到content.js
:
// Notification body.
const notification = document.createElement("div");
notification.className = 'acho-notification';
// Notification icon.
const icon = document.createElement('img');
icon.src = chrome.runtime.getURL("images/icon32.png");
notification.appendChild(icon);
// Notification text.
const notificationText = document.createElement('p');
notification.appendChild(notificationText);
// Add to current page.
document.body.appendChild(notification);
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
const notification = document.getElementsByClassName('acho-notification')[0];
const notificationText = notification.getElementsByTagName('p')[0];
notificationText.innerHTML = request.tabTitle;
notification.style.display = 'flex';
setTimeout(function () {
notification.style.display = 'none';
}, 5000);
return true;
});
现在让我们更仔细地检查一下前面的代码:
- 首先,我们创建一个
div
,作为通知主体。我们还为其分配了一个class
,以便稍后定义样式。 - 然后,我们将一个 附加
img
到上一个div
。这会将我们的扩展程序的图标添加到通知框中。- 要获取扩展程序的图标,我们必须使用
chrome.runtime.getURL
。请记住,内容脚本与扩展程序不在同一个上下文中运行,因此我们无法直接访问扩展程序的资源。这也是我们将文件icon32.png
作为manifest.json
Web可访问资源添加到 的原因。
- 要获取扩展程序的图标,我们必须使用
- 接下来,我们添加一个
p
元素,稍后我们将在其中附加通知文本。 - 最后,我们将通知附加到网页正文。
前 15 行代码将确保每个加载的页面都具有我们的通知结构。为了最终显示通知,我们为 添加了监听器chrome.runtime.onMessage
。让我们检查一下代码:
- 收到消息后,我们首先要在当前网页中找到通知的结构。我们使用
document.getElementsByClassName
获取通知的正文,然后p
使用 获取其中的元素getElementsByTagName
。 - 请记住,我们的脚本发送的消息
background.js
包含tabTitle
,因此我们使用该值request.tabTitle
并将其设置为通知文本元素的内容。 display
我们通过将属性设置为来确保我们的通知可见flex
。- 最后,我们用来
setTimeout
在 5 秒后再次隐藏通知。
太棒了!我们快完成了。让我们在文件中添加一些样式到通知中content.css
:
.acho-notification {
background-color: white;
border: rgb(242, 105, 77) 1px solid;
border-radius: 5px;
font-size: medium;
width: 320px;
display: none;
padding: 8px;
position: fixed;
bottom: 30px;
right: 30px;
align-items: center;
}
.acho-notification > img {
margin-right: 12px;
}
完毕!
就是这样!当用户按下 时,我们的通知将会是这样的Alt+Shift+3
:
仓库
我会不断更新这个 repo 中的所有 Chrome 扩展程序示例: