教程第 2 部分:使用 JavaScript 在网页中插入图像

2 部分示例:使用 JavaScript 在网页中插入图像 使用 JavaScript 代码将 stars.jpeg 图像插入当前打开的网页的顶部。 扩展的弹出窗口包含标题和标记为 “显示”的 HTML 按钮。 单击“ 显示 ”按钮时,JavaScript 会从扩展图标的弹出窗口发送消息,并在浏览器选项卡中动态插入作为内容运行的 JavaScript。

第 2 部分示例使用以下扩展技术:

  • 将 JavaScript 库注入扩展。
  • 向浏览器选项卡公开扩展资产。
  • 在现有浏览器选项卡中包括内容网页。
  • 让内容网页侦听来自弹出窗口的消息并做出响应。

通过“管理扩展”选项卡安装扩展后,你将从 “扩展 (扩展”图标) 按钮打开第 2 部分 扩展

单击扩展的图标打开扩展

该扩展在弹出窗口中显示一个小 HTML 页面,其中包含标题、说明和 “显示 ”按钮:

 选择“扩展”图标后显示popup.html

单击“ 显示 ”按钮时,JavaScript 代码会暂时插入 stars.jpeg 当前网页的顶部,将网页内容向下推送到图像下方。 注入的内容设置图像元素显示在 stars.jpeg 当前网页的顶部,然后在单击图像时删除图像:

浏览器中显示的图像

如果要立即安装并运行已完成的扩展,或查看其完成的代码,请执行以下任一操作:

然后,可以安装并运行存储库中已完成的扩展,每次 旁加载扩展以在本地安装和测试它。 在打开扩展之前,选项卡必须包含网页。

步骤 1:更新 popup.html 以包含按钮

若要使用本文,请先执行 教程第 1 部分:在弹出窗口中显示图像中的步骤;即克隆 MicrosoftEdge-Extensions 存储库,安装第 1 部分演示,然后运行该演示。

此步骤已在 MicrosoftEdge-Extensions 存储库的 popup.html 中完成。

如果要手动构建示例以添加 JavaScript,则此第 2 部分文章的假设起始状态是,第 2 部分代码存在一个目录,其中包含第 1 部分文章中创建的相同目录和文件。 这些目录可以是第 1 部分和第 2 部分的同级目录,如在 MicrosoftEdge-Extensions 存储库中所做的那样。

可以从 MicrosoftEdge-Extensions 存储库并排安装已完成的第 1 部分和第 2 部分演示。 建议先克隆存储库并安装并运行演示,然后 (,而不是从空目录开始) ,然后手动创建目录、创建文件并将代码粘贴到文件中。

若要手动展开已完成的第 1 部分演示以创建第 2 部分演示,需要执行以下操作:

  1. 在包含 popup.html 第 2 部分的文件的文件夹中, (最初是第 1 部分文件) 的副本,添加显示带有按钮的标题的标记。
  2. 包括对 JavaScript 文件的 popup.js引用。
  3. 编程该按钮。

下面是示例 HTML 文件:

/popup/popup.html (完成) :

<!DOCTYPE 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>(click the image to remove it from the webpage)</h2>
        <button id="sendmessageid">Display</button>
        <script src="popup.js"></script>
    </body>
</html>

执行 旁加载扩展中的步骤,在本地安装并测试扩展 ,以在本地更新扩展,然后运行扩展。 在打开扩展之前,选项卡必须包含网页。

更新并打开扩展后,将打开一个弹出窗口,其中包含一个小 HTML 页面,其中包含标题、说明和 “显示 ”按钮:

 单击扩展的图标后popup.html

步骤 2:更新网页以在顶部插入图像

添加“ 显示 ”按钮后,下一个任务是使按钮在活动选项卡中的网页顶部显示 images/stars.jpeg 图像文件。

每个选项卡页 (和扩展) 在其自己的线程中运行。 在下面的步骤中,你将创建一个注入到选项卡页的内容脚本。 注入的脚本会将消息从弹出窗口发送到在选项卡页上运行的内容脚本。 内容脚本将收到消息,该消息描述应显示哪个图像。

步骤 3:创建用于发送消息的弹出 JavaScript

此步骤已在 MicrosoftEdge-Extensions 存储库的 popup.js 中完成。 如果要手动创建第 2 部分扩展,请继续执行以下步骤。

popup/popup.js创建文件,然后在该文件中添加以下代码。

此代码向尚未创建的内容脚本发送一条消息,您必须立即创建该脚本并将其注入到浏览器选项卡中。为此,以下代码将事件 onclick 添加到弹出的 “显示 ”按钮:

/popup/popup.js (初始) :

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:

/popup/popup.js (完成) :

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 可从任何浏览器选项卡使用

此步骤已在 manifest.json MicrosoftEdge-Extensions 存储库中完成。 如果要手动创建第 2 部分扩展,请继续执行以下步骤。

images/stars.jpeg若要在任何浏览器选项卡中可用,必须使用 chrome.runtime.getURL API。

原因是使用 元素的 img 属性将图像src注入内容页。 内容页在与运行扩展的线程不同的唯一线程上运行。 必须将静态图像文件公开为 Web 资产,才能使其正常工作。

manifest.json 文件中添加另一个条目,以声明该图像可供所有浏览器选项卡使用。

该条目如下所示, (添加即将) 的内容脚本声明时,应在下面的完整 manifest.json 文件中看到它:

/manifest.json (部分) :

"web_accessible_resources": [
    {
      "resources": ["images/*.jpeg"],
      "matches": ["<all_urls>"]
    }
  ]

现在,你已在文件中编写了代码 popup.js ,用于将消息发送到嵌入在当前活动选项卡页上的内容页。

步骤 5:更新你的 manifest.json 新内容和 Web 访问

接下来,你将创建并注入嵌入到当前活动选项卡页上的内容页。 此步骤已在 manifest.json MicrosoftEdge-Extensions 存储库中完成。

包含 和 web_accessible_resourcescontent-scripts更新manifest.json如下所示:

/manifest.json (完成) :

{
    "name": "NASA picture of the day viewer",
    "version": "0.0.0.1",
    "manifest_version": 3,
    "description": "An extension that uses JavaScript to insert an image at the top of the webpage.",
    "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。 可以从 MicrosoftEdge-Extensions 存储库的 /lib/ 文件夹中复制该文件。

添加 jQuery

此步骤已在 MicrosoftEdge-Extensions 存储库的 jquery.min.js 中完成。

在要注入的内容脚本中,计划使用 jQuery ($) 。 你添加了 jQuery 的缩小版本,并将其作为 放在扩展包 lib\jquery.min.js中。

这些内容脚本在单独的沙盒中运行,这意味着注入到页面的 popup.js jQuery 不会与内容共享。

了解线程

即使浏览器选项卡在加载的网页上运行 JavaScript,注入的任何内容也无法访问该 JavaScript。 注入的 JavaScript 仅有权访问该浏览器选项卡中加载的实际 DOM。

步骤 6:添加内容脚本消息侦听器

若要继续手动构建第 2 部分演示,需要创建此文件。 此步骤已在 MicrosoftEdge-Extensions 存储库的 content.js 中完成。

content-scripts\content.js下面是根据 content-scripts 中的部分注入到每个浏览器选项卡页的文件manifest.json

/content-scripts/content.js (完成) :

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.jssendMessage 方法时,第一个参数的那些属性是 urlimageDivId

当侦听器处理事件时,将运行作为第一个参数的函数。 该函数的第一个参数是具有 由 sendMessage分配的属性的对象。 该函数只处理三个 jQuery 脚本行。

  • 第一个脚本行在浏览器选项卡的 正下方body追加一个img元素,该slide-image元素分配了 类,并imageDivId作为该图像元素的 ID。

  • 第二个脚本行将一个 <样式> 节动态插入到 DOM 标头中,必须将其作为 slide-image 类分配给元素 img

  • 第三个脚本行添加一个 click 事件,该事件涵盖整个图像,允许用户选择图像上的任意位置,并且该图像将从页面 (以及事件侦听器) 中删除。

步骤 7:安装和测试扩展

  1. 在“管理扩展”页中安装或更新扩展;请参阅 旁加载扩展以在本地安装和测试它

  2. 转到新窗口或选项卡中的网页,例如 Microsoft.com。选项卡不得为空,并且不得为“管理扩展”页。

  3. 单击“地址”栏旁边的“ 扩展 (扩展”图标) 按钮。 或者,选择 “设置和更多 (...) >扩展”。

    单击扩展的图标打开扩展

  4. 单击 美国宇航局日查看器扩展图片的 图标或名称。

    扩展的弹出窗口随即打开:

     选择“扩展”图标后显示popup.html

  5. 单击“ 显示 ”按钮。 stars.jpeg 插入当前选项卡当前网页顶部,将网页内容向下推送到图像下方:

    浏览器中显示的图像

  6. stars.jpeg单击填充网页顶部的图像。 该图像元素将从 DOM 树和网页中删除,并还原当前网页,将其内容移回选项卡顶部。

恭喜! 你已创建一个扩展,该扩展从扩展图标的弹出窗口发送消息,并在浏览器选项卡中动态插入作为内容运行的 JavaScript。注入的内容设置图像元素显示在 stars.jpeg 当前网页顶部,然后在单击图像时删除图像。

另请参阅

GitHub: