Chrome 扩展程序 101
本博客将讨论如何设置、构建和运行您自己的 Chrome 扩展程序。最后,您将能够创建一个简单的“日期倒计时”扩展程序,显示距离特定日期还有多少天。
我们走吧!
Chrome 扩展术语
清单.json
JSON 文件告诉 Chrome 该扩展程序的功能、需要的权限以及将使用的文件。
背景脚本
独立于用户所在网页并与其并行运行的脚本。它用于状态管理,并且始终只有一个活动实例。
内容脚本
在用户所在网页上下文中运行的脚本。它可以访问、读取和/或修改用户所访问页面的 DOM。
设置
为您的扩展程序创建一个文件夹,例如 Count-Down,并在其中创建一个名为 的文件manifest.json
。在该文件中,添加清单版本、扩展程序名称、描述以及扩展程序的初始版本。该文件现在应该类似于此。
{
"manifest_version": 3,
"name": "Count Down Days",
"version": "1.0",
"description": "Takes a date input and displays the number of days left until the given date"
}
文件和文件夹结构
现在我们开始创建其余元素。
- 根文件夹中有一个名为background.js的文件。这将是我们的后台脚本。
- 根文件夹中有一个名为content的文件夹,其中包含:
- 一个名为popup.html的 HTML 文件。此文件将包含扩展程序下拉菜单的标记
- 一个名为popup.js的 JS 文件。这是我们的内容脚本
- 一个名为 popup.css 的 CSS 文件,用于设置下拉菜单中的元素样式
- 图像文件夹(扩展图标和其他 - 可选)
将文件链接到manifest.json
我们将在manifest.json中引用后台脚本和 HTML 文件,如下所示。
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "content/popup.html",
"default_icon": {
"16": "images/icon16.png", // optional
"24": "images/icon24.png", // optional
"32": "images/icon32.png" // optional
}
}
图标最初由manifest.json 文件中 action 条目的default_icon键设置。该键接受一个包含图片大小和路径的字典。如果未指定图标,Chrome 会自动分配一个图标。
manifest.json现在应该如下所示:
{
"manifest_version": 3,
"name": "Count Down Days",
"version": "0.1",
"description": "Takes a date input and displays the day count left to the given date ",
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "content/popup.html",
"default_icon": {
"16": "/images/timer.png",
"128": "/images/timer.png",
"48": "/images/timer.png",
"256": "/images/timer.png"
}
}
}
运行扩展
打开 Chrome 浏览器并点击以下 URL:
chrome://extensions
在右上角,您应该会看到一个名为“开发者模式”的切换按钮。
勾选该按钮。
现在,您应该会看到一组用于加载、打包和更新扩展程序的选项。
选择“加载解压后的扩展程序”选项。
现在,从文件系统中选择扩展程序的根文件夹。
扩展程序将加载到浏览器中。
授予扩展权限
对于此扩展,我们将使用以下权限:
- activeTab - 允许访问当前活动的 Chrome 标签页。在本例中,我们需要此权限,因为我们要将标签页添加到当前活动的标签页。
- 脚本- 允许在当前网页上下文中运行脚本。我们使用此权限来注入执行日期操作的监听器事件。
- 存储- 允许在 Chrome 中存储对象。我们将使用此权限将日期字符串存储在 Chrome 存储中。
在manifest.json中添加以下行
“权限”:[“activeTab”,“存储”,“脚本”]
添加逻辑
打开background.js并添加以下代码:
let date = "08 15 2021";
chrome.runtime.onInstalled.addListener(() => {
chrome.storage.sync.set({ date });
console.log("Default Date set to Aug 15, 2021");
});
chrome.runtime是一个 API,允许扩展程序检索后台页面、监听并响应事件。
我们在这里所做的实际上是使用该 API 将一个默认日期字符串保存到 Chrome 存储中。稍后,我们的内容脚本可以访问此值。我们还添加了一个日志语句,用于测试。
在popup.html中,我们添加了两个按钮(一个用于显示剩余天数,另一个用于接受新的日期)。我们在此文件中引用样式popup.css和内容脚本popup.js,如下所示。
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="popup.css" />
</head>
<body>
<div class="buttons">
<button id="showDays">
<img class="img-icon" src="../images/timer.png" alt="Sand Clock" />
</button>
<button id="changeDate">
<img class="img-icon" src="../images/change-date.png" alt="Change Date Icon" />
</button>
</div>
<script src="popup.js"></script>
</body>
</html>
我为按钮使用了图像图标。资源可在下方 Github 链接中找到。让我们在popup.css文件中添加一些基本样式,如下所示。
button {
height: 30px;
width: 30px;
outline: none;
margin: 10px;
border: none;
border-radius: 2px;
}
button img {
width: 100%;
height: auto;
}
当前页面无法访问这些样式。保存后,我们返回浏览器,在chrome://extensions标签页中找到我们的扩展程序。每个扩展程序的右下角都有一个刷新图标。
刷新扩展程序,然后点击Service Worker超链接,即可查看 Service Worker(即background.js)的日志。现在,我们将能够在控制台中看到默认日期日志。
下一步是查看扩展程序的下拉菜单。打开另一个标签页,在 Chrome 浏览器的右上角,新扩展程序将变成一个可点击的选项。点击该选项后,我们将看到如下所示的下拉菜单。
注意:Chrome 扩展程序无法在chrome:// URL上打开。
这些按钮还不会做任何事情,所以让我们添加可以执行魔术的听众。
在popup.js中添加以下两个函数
// Content script follows
function showDaysLeft() {
// get the date string from Chrome storage
chrome.storage.sync.get("date", ({ date }) => {
// create a new div that will be appended to the body
let daysElement = document.createElement("div");
// adding styles to the new div
daysElement.style.cssText = "position: absolute; color: black; top: 30px; left: 50%; transform: translateX(-50%); background-color: pink; z-index: 99999; padding: 1rem; border-radius: 10px; box-shadow: 3px 3px 6px #00000060";
// Date.parse converts Date string to milliseconds
// To get the number of days left we get the difference in milliseconds and divide by 86400000 (milliseconds in a day)
noOfDaysLeft = parseInt((Date.parse(new Date(date)) - Date.parse(new Date())) / (86400000));
let content = '';
if (noOfDaysLeft < 0) {
content = document.createTextNode("Deadline has already passed.Please set a new one. :D");
alert(daysElement);
} else {
content = document.createTextNode(noOfDaysLeft + " days until go time! B)");
}
// Append the text node to the div
daysElement.appendChild(content);
// Append the div to the body tag
document.body.appendChild(daysElement);
setTimeout(() => {
document.body.removeChild(daysElement)
}, 3000);
});
}
function resetDate() {
let newDate = " ";
let daysElement = document.createElement("div");
daysElement.style.cssText = "position: absolute; color: black; top: 30px; left: 50%; transform: translateX(-50%); background-color: pink; z-index: 99999; padding: 1rem; border-radius: 10px; box-shadow: 3px 3px 6px #00000060";
// Get the date string input through window.prompt
newDate = window.prompt("Enter date in the dd/mm/yyyy format");
dateArray = newDate.split("/");
dateString = dateArray[1] + " " + dateArray[0] + " " + dateArray[2];
newDate = Date.parse(new Date(dateString));
let content = '';
// Check if the format is right
if (newDate) {
noOfDaysLeft = parseInt((Date.parse(new Date(newDate)) - Date.parse(new Date())) / (86400000));
if (noOfDaysLeft < 0) {
content = document.createTextNode("Are you time travelling to the past? I am not ready for you yet :D");
} else {
content = document.createTextNode("New date saved! \n" + noOfDaysLeft + " days until go time! B)");
// save the new date
chrome.storage.sync.set({ "date": newDate });
}
} else {
content = document.createTextNode("Enter a valid date - date/month/full-year");
}
daysElement.appendChild(content);
document.body.appendChild(daysElement);
setTimeout(() => {
document.body.removeChild(daysElement)
}, 3000);
}
函数逻辑在注释中解释。现在我们不能直接将监听器附加到按钮上。我们使用chrome.scripting API 将监听器注入到当前页面,如下所示:
// Initialize buttons
let showDays = document.getElementById("showDays");
let changeDate = document.getElementById("changeDate");
// When the button is clicked, inject showDaysLeft and resetDate into current page
showDays.addEventListener("click", async () => {
let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
chrome.scripting.executeScript({
target: { tabId: tab.id },
function: showDaysLeft,
});
});
changeDate.addEventListener("click", async () => {
let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
chrome.scripting.executeScript({
target: { tabId: tab.id },
function: resetDate,
});
});
注意:除了注入的监听器之外,其他函数/变量不能直接运行。
大功告成!😎 现在扩展程序已准备好进行测试。返回浏览器,刷新扩展程序,然后在新的标签页上测试它。输出结果应该类似于下面的 gif。
希望以上内容对您有所帮助。完整项目已发布在Github上。如有任何疑问,请通过Twitter联系我,或在下方评论区留言。✌️
文章来源:https://dev.to/venkyakshaya/chrome-extensions-101-3dif