创建扩展教程,第 2 部分
若要查看本教程这一部分的完整扩展包源,请转到 MicrosoftEdge-Extensions 存储库 > 扩展-getting-started-part2。
源代码已从清单 V2 更新到清单 V3。
本教程介绍以下扩展技术:
- 将 JavaScript 库注入扩展。
- 向浏览器选项卡公开扩展资产。
- 在现有浏览器选项卡中包括内容页。
- 让内容页侦听来自弹出窗口的消息并做出响应。
你将了解如何更新弹出菜单,以将静态星形图像替换为标题和标准 HTML 按钮。 选中该按钮后,会将星形图像传递到内容页。 此图像现在嵌入到扩展中,并插入活动浏览器选项卡。下面是步骤。
这些步骤要求完成初始扩展包步骤的步骤。 对于本教程,请转到 MicrosoftEdge-Extensions 存储库 > 扩展-getting-started-part1。
步骤 1:更新pop-up.html以包含按钮
在从本教程的初始部分创建popup.html
文件的弹出文件夹中,你将添加标记,以显示带有按钮的标题。 稍后将在其他步骤中对该按钮进行编程,但现在包括对空 JavaScript 文件的 popup.js
引用。
下面是更新的 HTML 文件示例:
<html>
<head>
<meta charset="utf-8" />
<style>
body {
width: 500px;
}
button {
background-color: #336dab;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
font-size: 16px;
}
</style>
</head>
<body>
<h1>Display the NASA picture of the day</h1>
<h2>(select the image to remove)</h2>
<button id="sendmessageid">Display</button>
<script src="popup.js"></script>
</body>
</html>
更新并打开扩展后,将打开一个弹出窗口,其中包含显示按钮。
步骤 2:更新popup.html以在浏览器选项卡顶部显示图像
添加按钮后,下一个任务是使其在活动选项卡页顶部显示 images/stars.jpeg
图像文件。
每个选项卡页 (和扩展) 在其自己的线程中运行。 创建注入到选项卡页的内容脚本。 然后,从弹出窗口将消息发送到在选项卡页上运行的内容脚本。 内容脚本将收到消息,该消息描述应显示哪个图像。
步骤 3:创建用于发送消息的弹出 JavaScript
popup/popup.js
创建文件并添加代码,以便向尚未创建的内容脚本发送消息,必须立即创建该脚本并将其注入到浏览器选项卡中。为此,以下代码将事件onclick
添加到弹出的“显示”按钮:
const sendMessageId = document.getElementById("sendmessageid");
if (sendMessageId) {
sendMessageId.onclick = function() {
// do something
};
}
在 事件中 onclick
,找到当前浏览器选项卡。然后,使用 chrome.tabs.sendmessage
扩展 API 向该选项卡发送消息。
在该消息中,必须包含要显示的图像的 URL。 确保发送唯一 ID 以分配给插入的图像。
若要发送要分配给插入图像的唯一 ID,可以使用以下几种不同的方法:
- 方法 1:让内容插入 JavaScript 生成该图像 ID。 我们不会在这里使用这种方法,因为后来变得明显的原因。
- 方法 2:在 中
popup.js
在此处生成该唯一 ID,然后将该 ID 传递给尚未创建的内容脚本。 我们将使用此方法。
以下代码概述了 中 popup/popup.js
更新的代码。 还可以传入当前选项卡 ID,本文稍后会用到该 ID:
const sendMessageId = document.getElementById("sendmessageid");
if (sendMessageId) {
sendMessageId.onclick = function() {
chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
chrome.tabs.sendMessage(
tabs[0].id,
{
url: chrome.runtime.getURL("images/stars.jpeg"),
imageDivId: `${guidGenerator()}`,
tabId: tabs[0].id
},
function(response) {
window.close();
}
);
function guidGenerator() {
const S4 = function () {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
};
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
}
});
};
}
步骤 4:使你 stars.jpeg
可从任何浏览器选项卡使用
images/stars.jpeg
若要在任何浏览器选项卡中可用,必须使用 chrome.runtime.getURL
API。
注意:如果使用清单 V2,请改用 chrome.extension.getURL
。 附加了映像后,会 getURL
返回该额外的前缀,如下所示: httpextension://inigobacliaghocjiapeaaoemkjifjhp/images/stars.jpeg
原因是使用 元素的 img
属性将图像src
注入内容页。 内容页在与运行扩展的线程不同的唯一线程上运行。 必须将静态图像文件公开为 Web 资产,才能使其正常工作。
在 manifest.json
文件中添加另一个条目,以声明该图像可供所有浏览器选项卡使用。 该条目如下所示, (添加即将) 的内容脚本声明时,应在下面的完整 manifest.json
文件中看到它:
"web_accessible_resources": [
{
"resources": ["images/*.jpeg"],
"matches": ["<all_urls>"]
}
]
现在,你已在文件中编写了代码 popup.js
以将消息发送到嵌入在当前活动选项卡页上的内容页,但尚未创建和注入该内容页。 立即执行此操作。
步骤 5:更新你的 manifest.json
新内容和 Web 访问
包含 和 web_accessible_resources
的content-scripts
更新manifest.json
如下所示:
{
"name": "NASA picture of the day viewer",
"version": "0.0.0.1",
"manifest_version": 3,
"description": "An extension to display the NASA picture of the day.",
"icons": {
"16": "icons/nasapod16x16.png",
"32": "icons/nasapod32x32.png",
"48": "icons/nasapod48x48.png",
"128": "icons/nasapod128x128.png"
},
"action": {
"default_popup": "popup/popup.html"
},
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["lib/jquery.min.js","content-scripts/content.js"]
}
],
"web_accessible_resources": [
{
"resources": ["images/*.jpeg"],
"matches": ["<all_urls>"]
}
]
}
属性 matches
设置为 <all_urls>
,这意味着加载每个选项卡时,中的所有 content_scripts
文件都会注入到所有浏览器选项卡页中。 允许注入的文件类型为 JavaScript 和 CSS。 还添加了 lib\jquery.min.js
。 可以从部分顶部提到的下载中包含该内容。
添加 jQuery
在要注入的内容脚本中,计划使用 jQuery ($
) 。 你添加了 jQuery 的缩小版本,并将其作为 放在扩展包 lib\jquery.min.js
中。 这些内容脚本在单独的沙盒中运行,这意味着注入到页面的 popup.js
jQuery 不会与内容共享。
了解线程
请记住,即使浏览器选项卡在加载的网页上运行 JavaScript,注入的任何内容也无法访问该 JavaScript。 注入的 JavaScript 仅有权访问该浏览器选项卡中加载的实际 DOM。
步骤 6:添加内容脚本消息侦听器
下面是 content-scripts\content.js
根据分区 manifest.json
content-scripts
注入到每个浏览器选项卡页中的文件:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
$("body").prepend(
`<img src="${request.url}" id="${request.imageDivId}"
class="slide-image" /> `
);
$("head").prepend(
`<style>
.slide-image {
height: auto;
width: 100vw;
}
</style>`
);
$(`#${request.imageDivId}`).click(function() {
$(`#${request.imageDivId}`).remove(`#${request.imageDivId}`);
});
sendResponse({ fromcontent: "This message is from content.js" });
});
请注意,上述 JavaScript 所做的所有操作都是使用chrome.runtime.onMessage.addListener
扩展 API 方法注册 listener
。 此侦听器等待消息(如前面所述的使用chrome.tabs.sendMessage
扩展 API 方法发送popup.js
的消息)。
方法的第一个参数 addListener
是函数,其第一个参数 request 是传入的消息的详细信息。 请记住,在使用 popup.js
sendMessage
方法时,第一个参数的那些属性是 url
和 imageDivId
。
当侦听器处理事件时,将运行作为第一个参数的函数。 该函数的第一个参数是具有 由 sendMessage
分配的属性的对象。 该函数只处理三个 jQuery 脚本行。
第一个脚本行在浏览器选项卡的 正下方
body
追加一个img
元素,该slide-image
元素分配了 类,并imageDivId
作为该图像元素的 ID。第二个脚本行将一个 <样式> 节动态插入到 DOM 标头中,必须将其作为
slide-image
类分配给元素img
。第三个脚本行添加一个
click
事件,该事件涵盖整个图像,允许用户选择图像上的任意位置,并且该图像将从页面 (以及事件侦听器) 中删除。
- 添加功能以在选中时删除显示的图像
现在,当你浏览到任何页面并选择 “扩展” 图标时,弹出菜单将显示如下:
选择 Display
按钮时,将得到以下内容。 如果选择图像上的 stars.jpeg
任意位置,则会删除该图像元素,并且选项卡页将折叠 回最初显示的内容:
祝贺你! 你已创建了一个扩展,该扩展成功从扩展图标弹出窗口发送消息,并在浏览器选项卡上动态插入了作为内容运行的 JavaScript。注入的内容设置图像元素以显示静态星形 .jpeg
文件。