Heim >Web-Frontend >CSS-Tutorial >So erstellen Sie eine Browsererweiterung
Möglicherweise verwenden Sie eine Browser -Erweiterung. Einige Erweiterungen sind sehr beliebt und nützlich, wie Anzeigenblocker, Kennwortmanager und PDF -Zuschauer. Diese Erweiterungen (oder "Add -Ons") sind nicht darauf beschränkt - Sie können mehr mit ihnen tun! In diesem Artikel wird erläutert, wie eine Erweiterung erstellt wird. Schließlich werden wir es in mehreren Browsern zum Laufen bringen.
Wir werden eine Erweiterung namens "Reddit Transkription" erstellen, die die Reddit-Zugänglichkeit verbessert, indem bestimmte Kommentare an die Spitze des Kommentarbereichs verschoben und dem Bildschirmleser Aria-Attribut hinzugefügt werden. Wir werden unsere Erweiterung auch noch einen Schritt weiter gehen, indem wir Optionen hinzufügen, um Kommentaren für einen besseren Textkontrast Grenzen und Hintergründe hinzuzufügen.
Die ganze Idee ist, Ihnen eine gute Vorstellung davon zu geben, wie Sie Browserverlängerungen entwickeln können. Wir werden zunächst Erweiterungen für Browser auf Chrombasis erstellen, z. B. Google Chrome, Microsoft Edge, Brave usw. In zukünftigen Artikeln werden wir die Erweiterung portieren, um sie mit Firefox kompatibel zu machen, und kürzlich Safari für die Unterstützung von Web -Erweiterungen in seinen MacOS- und iOS -Versionen von Browsern hinzugefügt.
Ist die Github -Codebasis bereit? Lassen Sie es uns Schritt für Schritt machen.
Erstens brauchen wir einen Projektarbeitsbereich. Alles, was wir wirklich brauchen, ist, einen Ordner zu erstellen und ihn zu benennen (ich habe ihn Transistoren von Reddit genannt). Erstellen Sie dann einen Ordner namens SRC für unseren Quellcode.
Ein Einstiegspunkt ist eine Datei, die allgemeine Informationen zur Erweiterung (d. H. Der Erweiterungsname, die Beschreibung usw.) enthält und die zu ausgeführten Berechtigungen oder Skripte definiert.
Unser Einstiegspunkt kann die Manifest.json -Datei in dem gerade erstellten SRC -Ordner sein. Fügen wir darin die folgenden drei Eigenschaften hinzu:
<code>{ "manifest_version": 3, "name": "Reddit 转录器", "version": "1.0" }</code>
Manifest_version ähnelt der Version in NPM oder Knoten. Es definiert, welche APIs verfügbar sind (oder nicht verfügbar). Wir werden die neueste Version 3 (auch als MV3 bekannt) für hochmoderne Arbeiten verwenden.
Die zweite Eigenschaft ist der Name, der unseren Erweiterungsnamen angibt. Dieser Name ist der Name, den unsere Erweiterung erscheint, wenn sie überall erscheint, wie z.
Dann gibt es eine Version. Es markiert die Erweiterung mit einer Versionsnummer. Denken Sie daran, dass diese Eigenschaft (im Gegensatz zu Manifest_version) eine Zeichenfolge ist, die nur Zahlen und Punkte enthalten kann (z. B. 1.3.5).
Tatsächlich können wir mehr hinzufügen, um den Kontext der Erweiterung hinzuzufügen. Zum Beispiel können wir eine Beschreibung bereitstellen, die die Funktionalität einer Erweiterung erläutert. Es ist am besten, diese Informationen bereitzustellen, da sie den Benutzern ein besseres Verständnis dafür vermitteln, was sie bei der Verwendung der Erweiterung begegnen werden.
In diesem Beispiel fügen wir nicht nur eine Beschreibung hinzu, sondern auch die Symbole und URLs, auf die der Chrome -Web -Store auf der Erweiterungsseite verweist.
<code>{ "description": "使Reddit 对残疾用户更易于访问。", "icons": { "16": "images/logo/16.png", "48": "images/logo/48.png", "128": "images/logo/128.png" }, "homepage_url": "https://www.php.cn/link/530ebdeb0491c0459e00298fcdb3a2bd/extensions/tor/" }</code>
Einer der großen Vorteile von Erweiterungen besteht darin, dass Ihre API es Ihnen ermöglicht, direkt mit Ihrem Browser zu interagieren. Wir müssen diese Berechtigungen jedoch der Erweiterung ausdrücklich erteilen, die auch in der Datei Manifest.json enthalten ist.
<code>{ "manifest_version": 3, "name": "Reddit 转录器", "version": "1.0", "description": "使Reddit 对残疾用户更易于访问。", "icons": { "16": "images/logo/16.png", "48": "images/logo/48.png", "128": "images/logo/128.png" }, "homepage_url": "https://www.php.cn/link/530ebdeb0491c0459e00298fcdb3a2bd/extensions/tor/", "permissions": [ "storage", "webNavigation" ] }</code>
Welche Berechtigungen haben wir gerade diese Verlängerung erteilt? Zuallererst Speicher. Wir möchten, dass diese Erweiterung die Einstellungen des Benutzers speichert. Daher müssen wir auf den Webspeicher des Browsers zugreifen, um sie zu speichern. Wenn der Benutzer beispielsweise möchte, dass der Kommentar einen roten Rand anzeigt, speichern wir die Einstellung zum nächsten Mal, anstatt sie erneut festlegen zu lassen.
Wir erteilen auch der Erweiterungsberechtigung, um zu sehen, wie Benutzer zum aktuellen Bildschirm navigieren. Reddit ist eine einzelne Seitenanwendung (SPA), was bedeutet, dass sie nicht die Seite aktualisiert. Wir müssen diese Interaktion "erfassen", da Reddit nur Kommentare für Beiträge lädt, wenn wir darauf klicken. Deshalb nutzen wir die Webnavigation.
Wir werden später den ausführenden Code auf der Seite abdecken, da ein brandneuer Eintrag in Manifest.json hinzugefügt werden muss.
/Erläuterung Abhängig von den zulässigen Berechtigungen kann der Browser dem Benutzer eine Warnung anzeigen, Berechtigungen zu akzeptieren. Es sind jedoch nur bestimmte Berechtigungen wie diese, und Chrome hat einen guten Überblick über diese Berechtigungen.
Die Browser-Erweiterung verfügt über eine integrierte internationalisierte API (I18N). Sie können Übersetzungen in mehreren Sprachen verwalten (vollständige Liste). Um die API zu verwenden, müssen wir unsere Übersetzung und Standardsprache in der Datei Manifest.json definieren:
<code>"default_locale": "en"</code>
Dies setzt Englisch als Sprache. Wenn der Browser auf eine andere Sprache eingestellt ist, die nicht unterstützt wird, fällt die Erweiterung zurück in das Standardgebietsschema (EN in diesem Beispiel).
Unsere Übersetzung ist im Verzeichnis _locales definiert. Erstellen wir einen Ordner darin, damit jede Sprache unterstützt wird. Jedes Unterverzeichnis hat eine eigene Nachrichten.json -Datei.
<code>src └─ _locales └─ en └─ messages.json └─ fr └─ messages.json</code>
Eine Übersetzungsdatei enthält mehrere Teile:
Hier ist ein Beispiel, das all dies zusammenbringt:
<code>{ "userGreeting": { // 翻译键(“id”) "message": "Good $daytime$, $user$!" // 翻译"description": "用户问候", // 翻译人员的可选描述"placeholders": { // 可选占位符"daytime": { // 如消息中所引用"content": "$1", "example": "morning" // 我们内容的示例值}, "user": { "content": "$1", "example": "Lars" } } } }</code>
Die Verwendung von Platzhaltern ist etwas schwierig. Zunächst müssen wir Platzhalter in der Nachricht definieren. Platzhalter müssen in $ Charaktere eingeschlossen sein. Danach müssen wir den Platzhalter zur "Platzhalterliste" hinzufügen. Dies ist etwas unintuitiv, aber Chrome möchte wissen, welcher Wert für unsere Platzhalter eingefügt werden soll. Wir möchten hier (anscheinend) dynamische Werte verwenden, daher verwenden wir einen speziellen Inhaltswert $ 1, um den von uns eingefügten Wert zu verweisen.
Die Beispieleigenschaft ist optional. Es kann verwendet werden, um den Übersetzer zu fordern, was der Platzhalter sein könnte (aber es zeigt sich nicht tatsächlich).
Wir müssen die folgende Übersetzung für unsere Erweiterung definieren. Kopieren Sie sie und fügen Sie sie in die Datei messus.json ein und fügen Sie sie ein. Fühlen Sie sich frei, weitere Sprachen hinzuzufügen (zum Beispiel, wenn Sie Deutsch sprechen, fügen Sie einen DE -Ordner in _locales hinzu und so weiter).
<code>{ "name": { "message": "Reddit 转录器" }, "description": { "message": "子reddits 的辅助图像描述。" }, "popupManageSettings": { "message": "管理设置" }, "optionsPageTitle": { "message": "设置" }, "sectionGeneral": { "message": "常规设置" }, "settingBorder": { "message": "显示评论边框" }, "settingBackground": { "message": "显示评论背景" } }</code>
Sie fragen sich vielleicht, warum wir uns ohne die i18n -Berechtigungen registriert haben, oder? Chrome ist in dieser Hinsicht etwas seltsam, da Sie nicht jede Berechtigung registrieren müssen. Einige (wie Chrome.I18n) benötigen keine Registrierung im Manifest. Andere Berechtigungen erfordern einen Eintrag, werden jedoch nicht an den Benutzer angezeigt, wenn die Erweiterung installiert ist. Einige andere Berechtigungen sind "gemischt" (z. B. Chrome.Runtime), was bedeutet, dass einige ihrer Funktionen ohne Erklärung der Berechtigungen verwendet werden können - aber andere Merkmale derselben API erfordern einen Eintrag, der im Manifest registriert ist. Sie müssen sich die Dokumentation ansehen, um diese Unterschiede vollständig zu verstehen.
Das erste, was Endbenutzer sehen, ist eine Eintrags- oder Erweiterungsübersichtsseite im Chrome -Webladen. Wir müssen die Manifestdatei anpassen, um sicherzustellen, dass alles übersetzt wird.
<code>{ // 更新这些条目"name": "__MSG_name__", "description": "__MSG_description__" }</code>
Wenn Sie diese Syntax anwenden, wird die entsprechende Übersetzung in der Datei messus.json verwendet (z. B. wird _msg -Name mit dem Namen übersetzt).
Das Anwenden von Übersetzungen in HTML -Dateien erfordert JavaScript.
<code>chrome.i18n.getMessage('name');</code>
Dieser Code gibt die von uns definierte Übersetzung zurück (d. H. Reddit Transcript). Platzhalter können auf ähnliche Weise durchgeführt werden.
<code>chrome.i18n.getMessage('userGreeting', { daytime: 'morning', user: 'Lars' });</code>
Das Anwenden der Übersetzung auf alle Elemente auf diese Weise kann umständlich sein. Wir können jedoch ein kleines Skript schreiben, das Übersetzung gemäß dem Datenattribut durchführt. Erstellen wir also einen neuen JS -Ordner im SRC -Verzeichnis und fügen Sie dann eine neue Util.js -Datei hinzu.
<code>src └─ js └─ util.js</code>
Dies kann die Aufgabe erfüllen:
<code>const i18n = document.querySelectorAll("[data-intl]"); i18n.forEach(msg => { msg.innerHTML = chrome.i18n.getMessage(msg.dataset.intl); }); chrome.i18n.getAcceptLanguages(languages => { document.documentElement.lang = languages[0]; });</code>
Nachdem wir dieses Skript zur HTML-Seite hinzugefügt haben, können wir dem Element ein Data-Intl-Attribut hinzufügen, um den Inhalt festzulegen. Die Dokumentsprache wird auch nach der Sprache des Benutzers festgelegt.
<code> </code>
<code>管理设置</code>
Bevor wir in die tatsächliche Programmierung eintauchen, müssen wir zwei Seiten erstellen:
Hier finden Sie einen Überblick über die Ordner und Dateien, die wir für die Seite erstellen müssen:
<code>src ├─ css | └─ paintBucket.css ├─ popup | ├─ popup.html | ├─ popup.css | └─ popup.js └─ options ├─ options.html ├─ options.css └─ options.js</code>
Die .css -Datei enthält reine CSS, das ist es. Ich werde nicht in Details eingehen, weil ich weiß, dass die meisten von Ihnen bereits ein vollständiges Verständnis dafür haben, wie CSS funktioniert. Sie können Stile aus dem Github -Repository des Projekts kopieren und einfügen.
Beachten Sie, dass das Popup keine Registerkarte ist, seine Größe hängt davon ab, was es sich darin befindet. Wenn Sie ein Popup mit fester Größe verwenden möchten, können Sie die Breiten- und Höheneigenschaften auf dem HTML-Element festlegen.
Dies ist ein HTML -Skelett, das CSS und JavaScript -Dateien und in verknüpft
Fügen Sie Titel und Schaltflächen hinzu. `` `
<code><meta charset="UTF-8"> <meta content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" name="viewport"> <meta content="ie=edge" http-equiv="X-UA-Compatible"></code> <title data-intl="name"></title><link href="../css/paintBucket.css" rel="stylesheet"><link href="popup.css" rel="stylesheet"><h1></h1>
<code>h1 包含扩展程序名称和版本;按钮用于打开选项页面。标题将不会填充翻译(因为它缺少data-intl 属性),并且按钮还没有任何点击处理程序,因此我们需要填充popup.js 文件:</code>
const title = document.getElementById ('title');
title.TextContent = ${manifest.name} (${manifest.version})
;
EinstellungenBTN.AdDeVentListener ('Click', () => {Chrome.Runtime.OpenOptionPage ();});
<code>此脚本首先查找manifest 文件。Chrome 提供了包含getManifest 方法的runtime API(此特定方法不需要runtime 权限)。它将我们的manifest.json 返回为JSON 对象。在我们使用扩展程序名称和版本填充标题后,我们可以向设置按钮添加事件侦听器。如果用户与之交互,我们将使用chrome.runtime.openOptionsPage() 打开选项页面(同样不需要权限条目)。弹出窗口页面现在已完成,但扩展程序尚不知道它的存在。我们必须通过将以下属性附加到manifest.json 文件来注册弹出窗口。</code>
"action": { "default_popup": "popup/popup.html", "default_icon": { "16": "images/logo/16.png", "48": "images/logo/48.png", "128": "images/logo/128.png" } },
<code>#### 创建选项页面创建此页面的过程与我们刚刚完成的过程非常相似。首先,我们填充options.html 文件。以下是一些我们可以使用的标记:</code>
<circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
<code><div></div></code> <p>Reddit Transkriptionistische Erweiterung von <a href="https://www.php.cn/link/530ebdeb0491c0459e00298fcdb3a2bd" target="_blank">Lars.koelker.dev</a> .</p>
Reddit ist eine eingetragene Marke von Reddit, Inc. Diese Erweiterung wird in keiner Weise mit Reddit, Inc. befürwortet oder in Verbindung gebracht.
<code>目前还没有实际的选项(只有它们的包装器)。我们需要编写选项页面的脚本。首先,我们在options.js 中定义变量以访问我们的包装器和默认设置。“冻结”我们的默认设置可以防止我们以后意外修改它们。</code>
const defaultSettings = Object.Freeze ({Border: False, Hintergrund: False,});
<code>接下来,我们需要加载保存的设置。我们可以为此使用(先前注册的)存储API。具体来说,我们需要定义是要在本地存储数据(chrome.storage.local) 还是通过登录的所有设备同步设置(chrome.storage.sync)。让我们在这个项目中使用本地存储。需要使用get 方法检索值。它接受两个参数: 1. 我们要加载的条目2. 包含值的回调我们的条目可以是字符串(例如,下面的settings)或条目数组(如果我们想要加载多个条目,则很有用)。回调函数中的参数包含我们先前在{ settings: ... } 中定义的所有条目的对象:</code>
chrome.storage.local.get ('Einstellungen', ({Einstellungen}) => {const options = Einstellungen? DefaultSettings; // Wenn die Einstellungen nicht definiert sind, fallen Sie auf die Standardeinstellungen zurück, wenn (! Einstellungen) {Chrome.Storage.Local.set ({{Einstellungen: Standardsetinging,});})})})})})})})})})})})})})});})})})})})})})})})})})})})})})})})})})})})})})})})})});})})})})})})})})})})})})})})});
// Optionen erstellen und anzeigen const GeneralOptions = Object.Keys (Optionen) .Filter (x =>! X.Startswith ('Advanced'));
GeneralOptions.foreach (Option => createOption (Option, Optionen, Generalsection));
<code>为了呈现选项,我们还需要创建一个createOption() 函数。</code>
Funktion createOption (Einstellung, Einstellungen, Wrapper) {const SettingWrapper = <div><label for="${setting}">${chrome.i18n.getMessage(</label></div>
);
`;
const toggleSwitch = SettingWrapper.querySelector ("label.is-switch");
input.onchange = () => {TogglesSwitch.SetatTribute ('Aria-Check', input.Conted);
TogglesSwitch.onkeydown = e => {if (e.Key === "" || E.Key == "ENTER") {E.PreventDefault ();
Wrapper.AppendChild (SettingWrapper);
<code>在我们的开关(又名单选按钮)的onchange 事件侦听器中,我们调用函数updateSetting。此方法将把单选按钮的更新值写入存储中。为此,我们将使用set 函数。它有两个参数:我们要覆盖的条目和(可选)回调(在本例中我们不使用)。由于我们的settings 条目不是布尔值或字符串,而是一个包含不同设置的对象,因此我们使用扩展运算符(...) 并仅覆盖settings 对象中的实际键(setting)。</code>
Funktion updateSetting (Schlüssel, Wert) {Chrome.storage.local.get ('Einstellungen', ({Einstellungen}) => {Chrome.Storage.local.set ({Einstellungen: {... Einstellungen,
<code> } })</code>
});
<code>同样,我们需要通过将以下条目附加到manifest.json 来“通知”扩展程序我们的选项页面:</code>
"options_ui": {"open_in_tab": true, "page": "options/options.html"},
<code>根据您的用例,您还可以通过将open_in_tab 设置为false 来强制选项对话框作为弹出窗口打开。 ### 安装开发扩展程序现在我们已经成功设置了manifest 文件并将弹出窗口和选项页面都添加到了组合中,我们可以安装扩展程序来检查我们的页面是否正常工作。导航到chrome://extensions 并启用“开发者模式”。将出现三个按钮。单击标记为“加载解压”的按钮,然后选择扩展程序的src 文件夹以加载它。扩展程序现在应该已成功安装,并且我们的“Reddit 转录器”图块应该在页面上。我们现在已经可以与扩展程序交互了。单击地址栏旁边的拼图块(?) 图标,然后单击新添加的“Reddit 转录器”扩展程序。您现在应该会看到一个小的弹出窗口,其中包含一个按钮,用于打开选项页面。不错吧?在我的设备上它可能看起来有点不同,因为我在这些屏幕截图中启用了深色模式。如果您启用“显示评论背景”和“显示评论边框”设置,然后重新加载页面,则状态将保留,因为我们将其保存在浏览器的本地存储中。 ### 添加内容脚本好的,我们现在已经可以触发弹出窗口并与扩展程序设置交互,但是扩展程序本身还没有做任何特别有用的事情。为了让它发挥作用,我们将添加一个内容脚本。在js 目录中添加一个名为comment.js 的文件,并确保在manifest.json 文件中定义它:</code>
"content_scripts": [{"Matches": [" : //www.reddit.com/ "], "JS": ["js/comment.js"]}],
<code>content_scripts 由两部分组成: - matches:此数组保存URL,这些URL 告诉浏览器我们希望内容脚本在何处运行。作为Reddit 的扩展程序,我们希望它在与://www.redit.com/* 匹配的任何页面上运行,其中星号是通配符,用于匹配顶级域之后的任何内容。 - js:此数组包含实际的内容脚本。内容脚本无法与其他(普通)JavaScript 交互。这意味着如果网站的脚本定义了变量或函数,我们就无法访问它。例如:</code>
// script_on_website.js const username = 'lars';
// content_script.js console.log (Benutzername);
<code>现在让我们开始编写内容脚本。首先,我们在comment.js 中添加一些常量。这些常量包含稍后将使用的RegEx 表达式和选择器。CommentUtils 用于确定帖子是否包含“tor 评论”,或者是否存在评论包装器。</code>
const messagetypes = object.freeze ({comment_page: 'comment_page', subreddit_page: 'subreddit_page', main_page: 'main_page', other_page: 'other_page',});
const selectors = Object.freeze ({commentrapper: 'div [style = "-commentswrapper-Gradient-Color"]> Div, div [style = "max-height: unsertlich"]> div', TorCompment: 'Div [Data-Tor-Coment]', postkontent: 'Div [Data-Test-]' '});
const urlregex = Object.freeze ({commentpage:/\/r \/. \/commenter \/./ , subredDitPage: /\/r\/.*\//});
const commentutils = object.freeze ({isTorCompoment: (comment) => comment.querySelector ('[Data-Test-])? Kommentar : () => !! document.querySelector ('[data-reddit-coment-wrapper = "true"]')});
<code>接下来,我们检查用户是否直接打开评论页面(“帖子”),然后执行RegEx 检查并更新directPage 变量。当用户直接打开URL(例如,通过将其键入地址栏或单击另一个页面上的<a> 元素(例如Twitter))时,就会发生这种情况。</a></code>
lass DirectPage = false;
<code>除了直接打开页面外,用户通常还会与SPA 交互。为了捕获这种情况,我们可以通过使用runtime API 向comment.js 文件添加消息侦听器。</code>
chrome.runtime.onmessage.addListener (msg => {if (msg.type === MessAgetypes.comment_Page) {WaitForCompompment (movecommments);}});
<code>我们现在只需要这些函数。让我们创建一个moveComments() 函数。它将特殊的“tor 评论”移动到评论部分的开头。它还会根据设置中是否启用了边框,有条件地将背景颜色和边框应用于评论。为此,我们调用存储API 并加载settings 条目:</code>
Funktion movecomments () {if (commentutils.commentWrapperexists ()) {return;
const Wrapper ${Selectors.commentWrapper} > div
document.querySelector (selektorisch.comMentWrapper);
Wrapper.Dataset.RedDitComentWrapper = 'True';
if (DirectPage) {Kommentare = document.querySelectorAll ("[data-reddit-coment-wrapper = 'true']> div");
Chrome.Storage.Local.get ('Einstellungen', ({Einstellungen}) => {// Highlight 18 Kommentare.foreach (Kommentar => {if (commentutils.istorComment (comment) {comment.dataset.torcoment = 'true'; S.Border) {comment.style.outline = '2px Solid Red'; comment.style.order = "-1";
<code>applyWaiAria() 函数在moveComments() 函数中调用——它添加aria- 属性。另一个函数创建唯一标识符以与aria- 属性一起使用。</code>
Funktion applywaiaria (postcontent, comment) {const postMedia = postcontent.querySelector ('img [Klasse*= "ImageBox-Image"], Video');
if (! costmedia) {return;
comment.setattribute ('id', commentId);
Funktion uUidv4 () {return 'xxxxxxx-xxxx-4xxxxxxx-xxxxxxxxxxxx'.Replace (/[xy]/g, Funktion (c) {var r = math.random () * 16 | 0, V ==' x '? }
<code>以下函数等待评论加载,如果找到评论包装器,则调用回调参数。</code>
Funktion WaitForComment (Callback) {const config = {Childlist: true, subtree: true};
Observer.observe (Dokument.DocumentElement, const);
Funktion startObseringTimeout (Beobachter, Sekunden) {return setTimeout () => {observer.disconnect ();}, 1000 * Sekunden);
<code>### 添加服务工作者还记得我们在内容脚本中添加了消息侦听器吗?此侦听器当前未接收消息。我们需要自己将其发送到内容脚本。为此,我们需要注册一个服务工作者。我们必须通过将以下代码附加到manifest.json 来注册服务工作者:</code>
"Hintergrund": {"service_worker": "sw.js"}
<code>不要忘记在src 目录中创建sw.js 文件(服务工作者始终需要在扩展程序的根目录src 中创建)。现在,让我们为消息和页面类型创建一些常量:</code>
const messagetypes = object.freeze ({comment_page: 'comment_page', subreddit_page: 'subreddit_page', main_page: 'main_page', other_page: 'other_page',});
const urlregex = Object.freeze ({commentpage:/\/r \/. \/commenter \/./ , subredDitPage: /\/r\/.*\//});
const utils = Object.freeze ({getPagetype: (url) => {if (neue URL (URL) .PathName === '/') {return Messagetypes.main_page;} else if (urlregex.commentPage {Return MessAntypes.Subreddit_page;
<code>return messageTypes.OTHER_PAGE;</code>
}});
<code>我们可以添加服务工作者的实际内容。我们使用历史状态上的事件侦听器(onHistoryStateUpdated) 来执行此操作,该侦听器检测何时使用History API 更新页面(通常在SPA 中用于在没有页面刷新情况下导航)。在此侦听器中,我们查询活动选项卡并提取其tabId。然后,我们将包含页面类型和URL 的消息发送到我们的内容脚本。</code>
chrome.webnavigation.onHistoryStateUpdated.addListener (async ({url}) => {const [{id: tabid}] = warte Chrome.tabs.Query ({active: true: true, currentWindow: true});
chrome.tabs.sendMessage (tabid, {type: utils.getPagetype (url), url});
<code>### 全部完成!我们完成了!导航到Chrome 的扩展程序管理页面(chrome://extensions),然后点击解压扩展程序上的重新加载图标。如果您打开包含“Reddit 转录器”评论和图像转录的Reddit 帖子(例如此帖子),只要我们在扩展程序设置中启用了它,它就会被移动到评论部分的开头并突出显示。 ### 结论这是否像您想象的那么难?在我深入研究之前,它肯定比我想象的要简单得多。在设置manifest.json 并创建任何我们需要的文件和资产后,我们真正做的只是像往常一样编写HTML、CSS 和JavaScript。如果您在途中遇到任何问题,Chrome API 文档是一个很好的资源,可以帮助您重回正轨。再次声明,这是包含我们在本文中介绍的所有代码的GitHub 代码库。阅读它,使用它,并让我知道您的想法!</code>
Das obige ist der detaillierte Inhalt vonSo erstellen Sie eine Browsererweiterung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!