Google Chrome-Erweiterungen entwickeln
() translation by (you can also view the original English article)
Es ist kein Geheimnis, dass mein Lieblingsbrowser Google Chrome ist. Ich mag es, weil es schnell ist, zuverlässig, es stürzt nicht ab (sehr oft), und es sieht gut aus. Es gibt noch etwas, das ich noch wertvoller finde. Es ist die Tatsache, dass Sie eine Erweiterung dafür nur mit HTML, CSS und JavaScript erstellen können. Ich unterstütze immer solche Produkte, Produkte, die offen für die Community sind und Chrome ist eines dieser Produkte. Wenn Sie etwas benötigen und es noch nicht implementiert ist, können Sie es selbst entwickeln.
Am Ende dieses Artikels finden Sie eine funktionierende Chrome-Erweiterung, die die meisten der unten erläuterten Techniken verwendet. Sie können das letzte Beispiel mit der Schaltfläche zum Herunterladen des Quellcodes oben auf dieser Seite herunterladen.
Warum Sie Ihre eigene Erweiterung schreiben sollten
Ich ermutige immer Leute, bessere Werkzeuge zu verwenden, um ihren Arbeitsfluss zu beschleunigen. Die Software, die wir verwenden, sollte uns helfen, wir sollten nicht damit kämpfen müssen. Das Entwickeln von Erweiterungen / Plugins für Ihren bevorzugten Editor oder Browser hilft nicht nur Ihnen, sondern auch anderen Programmierern, die früher oder später in der gleichen Situation sein werden. Wenn etwas fehlt, kannst du es selbst bauen und mit Chrome ist das wirklich einfach. Die Modellierung Ihrer Umgebung um Ihre Bedürfnisse herum ist der Schlüssel zu hoher Produktivität.
Entwickeln und testen Sie Ihre Erweiterungen
Zum Glück gibt es eine Möglichkeit, Ihre Erweiterung zu testen, ohne sie in den Web-Shop von Chrome hochladen zu müssen. Geben Sie in die Adresszeile Ihres Browsers Folgendes ein:
1 |
chrome://extensions |
Stellen Sie sicher, dass Sie den Entwicklermodus überprüfen und auf die Schaltfläche Entpackte Erweiterung laden klicken. Wählen Sie dann einfach den Ordner von Ihrer Festplatte, der die Dateien der Erweiterung enthält.



Die Architektur
Hier ist ein Diagramm der Architektur für eine Chrome-Erweiterung:



Und jetzt wollen wir uns jedes Element in der Architektur genauer ansehen.
Manifest
Der Einstiegspunkt Ihrer Erweiterung ist die Datei manifest.json. Es sollte ein gültiges JSON-Objekt enthalten. Beispielsweise:
1 |
{
|
2 |
"name": "BrowserActionExtension", |
3 |
"version": "0.0.1", |
4 |
"manifest_version": 2, |
5 |
"browser_action": { |
6 |
"default_title": "That's the tool tip", |
7 |
"default_popup": "popup.html" |
8 |
}
|
9 |
}
|
Die erforderlichen Eigenschaften sind name
, version
und manifest_version
. Die version
kann irgendwo von eins bis vier, durch Punkte getrennte Ganzzahlen sein. Es ist etwas, das von Google Autoupdate-System verwendet wird. So weiß es, wann Sie Ihre Erweiterung aktualisieren müssen. Der Wert der manifest_version
sollte die Ganzzahl 2
sein.
Das Manifest könnte andere Eigenschaften enthalten, abhängig von der Art der Erweiterung, die Sie benötigen, aber ich werde nur diejenigen beschreiben, die ich für interessanter halte.
Hintergrundseiten
Jede Erweiterung hat eine unsichtbare Hintergrundseite, die vom Browser ausgeführt wird. Es gibt zwei Arten - persistente Hintergrundseiten und Ereignisseiten. Der erste ist die ganze Zeit aktiv. Die zweite ist nur aktiv, wenn sie benötigt wird. Google ermutigt Entwickler, Ereignisseiten zu verwenden, da dies Speicher spart und die Gesamtleistung des Browsers verbessert. Es ist jedoch gut zu wissen, dass Sie hier auch Ihre Hauptlogik und Initialisierung eingeben sollten. Normalerweise spielt die Hintergrundseite / das Skript die Rolle einer Brücke zwischen den anderen Teilen der Erweiterung.
Hier ist, wie Sie es im Manifest beschreiben sollten:
1 |
"background": { |
2 |
"scripts": ["background.js"], |
3 |
"persistent": false/true |
4 |
}
|
Wie Sie vielleicht vermutet haben, verwenden Sie persistent
, wenn die persistente Eigenschaft false
ist. Ansonsten arbeiten Sie mit einer persistenten Hintergrundseite.
Inhaltsskript
Wenn Sie Zugriff auf das DOM der aktuellen Seite benötigen, müssen Sie ein Inhaltsskript verwenden. Der Code wird im Kontext der aktuellen Webseite ausgeführt, was bedeutet, dass er bei jeder Aktualisierung ausgeführt wird. Verwenden Sie die folgende Syntax, um ein solches Skript hinzuzufügen.
1 |
"content_scripts": [ |
2 |
{
|
3 |
"matches": ["https://*/*", "https://*/*"], |
4 |
"js": ["content.js"] |
5 |
}
|
6 |
]
|
Beachten Sie, dass der Wert der Übereinstimmungen matches
, für welche Seiten Ihr Skript verwendet wird. Lesen Sie mehr über matchmuster hier.
Benutzeroberfläche
Es gibt verschiedene Möglichkeiten, die Benutzeroberfläche Ihrer Erweiterung zu erstellen. Hier sind die vier beliebtesten.
Hier sind die vier beliebtesten.
Die meisten Entwickler verwenden die Eigenschaft browser_action
, um ihre Plugins zu erstellen. Sobald Sie es festgelegt haben, wird ein Symbol für Ihre Erweiterung auf der rechten Seite der Adressleiste platziert. Benutzer können dann auf das Symbol klicken und ein Popup-Fenster öffnen, bei dem es sich um von Ihnen gesteuerte HTML-Inhalte handelt.



Die Manifestdateien sollten die folgenden Daten enthalten:
1 |
"browser_action": { |
2 |
"default_icon": { |
3 |
"19": "icons/19x19.png", |
4 |
"38": "icons/38x38.png" |
5 |
},
|
6 |
"default_title": "That's the tool tip", |
7 |
"default_popup": "popup.html" |
8 |
}
|
Der default_title
ist ein kleines Tooltip, das angezeigt wird, wenn der Benutzer sich über das Symbol bewegt. default_popup
ist eigentlich die HTML-Datei, die in das Popup geladen wird. Es gibt auch ein Abzeichen, das Sie über Ihr Symbol platzieren können. Sie können das in Ihrem Hintergrundskript tun. Beispielsweise:
1 |
chrome.browserAction.setBadgeText({text: "yeah"}); |
Dies war der Code, mit dem ich das obige Bild erzeugt habe.
Seitenaktion
Die Eigenschaft page_action
ähnelt der Aktion des Browsers, das Symbol wird jedoch in der Adressleiste angezeigt:



Das Interessante daran ist, dass dein Icon anfänglich ausgeblendet ist, also solltest du entscheiden, wann es angezeigt werden soll. Im obigen Bild wird das RSS-Symbol beispielsweise nur angezeigt, wenn die aktuelle Seite einen Link zum RSS-Feed enthält. Wenn Sie Ihr Icon ständig sehen müssen, sollten Sie browser_action
direkt verwenden.
Um die Seitenaktion hinzuzufügen, geben Sie den folgenden Code in Ihr Manifest ein:
1 |
"page_action": { |
2 |
"default_icon": { |
3 |
"19": "images/icon19.png", |
4 |
"38": "images/icon38.png" |
5 |
},
|
6 |
"default_title": "Google Mail", |
7 |
"default_popup": "popup.html" |
8 |
}
|
Im Gegensatz zum Symbol der Browseraktion verfügt das Symbol der Seitenaktion nicht über Ausweise.
Entwicklerwerkzeuge
Ich benutze DeveloperTools viel und es ist schön, dass Chrome eine Methode zum Hinzufügen neuer Registerkarten zu diesen Tools bietet. Als erstes sollten Sie eine HTML-Seite hinzufügen, die beim Öffnen des Panels geladen wird:
1 |
"devtools_page": "devtools.html" |
Sie müssen keinen HTML-Code in die Seite einfügen, außer zum Verknüpfen in einer JavaScript-Datei, die den Tab erstellt:
1 |
<script src="devtools.js"></script>; |
Fügen Sie dann den folgenden Code in die Datei devtools.js
ein:
1 |
chrome.devtools.panels.create( |
2 |
"TheNameOfYourExtension", |
3 |
"img/icon16.png", |
4 |
"index.html", |
5 |
function() { |
6 |
|
7 |
}
|
8 |
);
|
Nun fügt der obige Code eine neue Registerkarte mit dem Namen TheNameOfYourExtension
hinzu und sobald Sie darauf klicken, lädt der Browser index.html
in den DeveloperTools.
Omnibox
Die omnibox
ist das Schlüsselwort, das in der Adressleiste von Chrome angezeigt wird. Wenn Sie beispielsweise die folgende Eigenschaft zu Ihrem Manifest hinzufügen:
1 |
"omnibox": { "keyword" : "yeah" } |
Und dann fügen Sie den folgenden Code in Ihrem Hintergrundskript hinzu:
1 |
chrome.omnibox.onInputChanged.addListener(function(text, suggest) { |
2 |
suggest([ |
3 |
{content: text + " one", description: "the first one"}, |
4 |
{content: text + " number two", description: "the second entry"} |
5 |
]);
|
6 |
});
|
7 |
chrome.omnibox.onInputEntered.addListener(function(text) { |
8 |
alert('You just typed "' + text + '"'); |
9 |
});
|
Sie sollten in der Lage sein, yeah
in die Adressleiste einzugeben. Dann solltest du so etwas sehen:



Durch Drücken der Tabulatortaste wird der folgende Bildschirm angezeigt:



Mit der chrome.omnibox
API können Sie natürlich die Eingaben des Benutzers abfangen und auf diese Eingabe reagieren.
APIs
Es gibt viele verschiedene Dinge, die Sie in Ihrer Erweiterung tun können. Sie können beispielsweise auf die Lesezeichen oder den Verlauf des Benutzers zugreifen. Sie können verschieben, Registerkarten erstellen oder sogar die Größe des Hauptfensters ändern. Ich empfehle dringend, die Dokumentation zu überprüfen, um eine bessere Vorstellung davon zu bekommen, wie diese Aufgaben ausgeführt werden.
Was Sie wissen sollten, ist, dass nicht alle APIs in jedem Teil Ihrer Erweiterung verfügbar sind. Ihr Inhaltsskript kann beispielsweise nicht auf chrome.devtools.panels
zugreifen, oder das Skript auf der Registerkarte DeveloperTools kann das DOM der Seite nicht lesen. Also, wenn Sie sich fragen, warum etwas nicht funktioniert, könnte dies der Grund sein.
Nachrichten
Wie oben erwähnt, haben Sie nicht immer Zugriff auf die API, die Sie verwenden möchten. Wenn das der Fall ist, sollten Sie die Nachrichtenübergabe verwenden. Es gibt zwei Arten von Nachrichtenübermittlung: Einmalanfragen und langlebige Verbindungen.
Einmalige Anfragen
Diese Art der Kommunikation findet nur einmal statt. I.e. Sie senden eine Nachricht und warten auf eine Antwort. Sie könnten beispielsweise den folgenden Code in Ihr Hintergrundskript einfügen:
1 |
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) { |
2 |
switch(request.type) { |
3 |
case "dom-loaded": |
4 |
alert(request.data.myProperty); |
5 |
break; |
6 |
}
|
7 |
return true; |
8 |
});
|
Verwenden Sie dann den Code von unten in Ihrem Inhaltsskript:
1 |
window.addEventListener("load", function() { |
2 |
chrome.extension.sendMessage({ |
3 |
type: "dom-loaded", |
4 |
data: { |
5 |
myProperty: "value" |
6 |
}
|
7 |
});
|
8 |
}, true); |
Und so können Sie Informationen über das DOM der aktuellen Seite abrufen und in Ihrem Hintergrundskript verwenden, das normalerweise keinen Zugriff auf diese Daten hat.
Langlebige Verbindungen
Verwenden Sie diese Art der Nachrichtenübermittlung, wenn Sie einen persistenten Kommunikationskanal benötigen. Platzieren Sie in Ihrem Inhaltsskript den folgenden Code:
1 |
var port = chrome.runtime.connect({name: "my-channel"}); |
2 |
port.postMessage({myProperty: "value"}); |
3 |
port.onMessage.addListener(function(msg) { |
4 |
// do some stuff here
|
5 |
});
|
Und dann im Hintergrundskript:
1 |
chrome.runtime.onConnect.addListener(function(port) { |
2 |
if(port.name == "my-channel"){ |
3 |
port.onMessage.addListener(function(msg) { |
4 |
// do some stuff here
|
5 |
});
|
6 |
}
|
7 |
});
|
Seiten überschreiben
Überschreiben von Seiten ist eine gute Möglichkeit, Ihren Browser anzupassen. Sie können auch einige der Standardseiten in Chrome ersetzen. Sie können beispielsweise eine eigene Verlaufsseite erstellen. Fügen Sie dazu das folgende Code-Snippet hinzu:
1 |
"chrome_url_overrides" : { |
2 |
"<page to override>;": "custom.html" |
3 |
}
|
Die möglichen Werte für <page to override>
sind bookmarks
, history
und newtab
. Es ist irgendwie cool, eine new tab
Seite zu haben.
Eine Beispielerweiterung
Um diesen Artikel abzuschließen, habe ich mich dazu entschieden, ein einfaches Beispiel einzubauen, damit Sie das Gesamtbild besser verstehen können. Diese Beispielerweiterung verwendet die meisten der oben beschriebenen Dinge, um einfach eine #F00
Hintergrundfarbe für alle divs auf der aktuellen Seite festzulegen. Fühlen Sie sich frei, den Quellcode mithilfe der Schaltfläche am oberen Rand dieses Artikels herunterzuladen.
Die Manifestdatei
Natürlich habe ich mit der Manifest-Datei angefangen:
1 |
{
|
2 |
"name": "BrowserExtension", |
3 |
"version": "0.0.1", |
4 |
"manifest_version": 2, |
5 |
"description" : "Description ...", |
6 |
"icons": { "16": "icons/16x16.png", "48": "icons/48x48.png", "128": "icons/128x128.png" }, |
7 |
"omnibox": { "keyword" : "yeah" }, |
8 |
"browser_action": { |
9 |
"default_icon": { "19": "icons/19x19.png", "38": "icons/38x38.png" }, |
10 |
"default_title": "That's the tool tip", |
11 |
"default_popup": "browseraction/popup.html" |
12 |
},
|
13 |
"background": { |
14 |
"scripts": ["background.js"], |
15 |
"persistent": false |
16 |
},
|
17 |
"chrome_url_overrides" : { |
18 |
"newtab": "newtab/newtab.html" |
19 |
},
|
20 |
"content_scripts": [{ |
21 |
"matches": ["http://*/*", "https://*/*"], |
22 |
"js": ["content.js"] |
23 |
}],
|
24 |
"devtools_page": "devtools/devtools.html" |
25 |
}
|
Denken Sie daran, dass Sie Ihre Dateien in Ordnern organisieren können. Beachten Sie auch die version
seigenschaft. Sie sollten diese Eigenschaft jedes Mal aktualisieren, wenn Sie Ihre Erweiterung in den Web Store hochladen möchten.
Hintergrundskript
1 |
// omnibox
|
2 |
chrome.omnibox.onInputChanged.addListener(function(text, suggest) { |
3 |
suggest([ |
4 |
{content: "color-divs", description: "Make everything red"} |
5 |
]);
|
6 |
});
|
7 |
chrome.omnibox.onInputEntered.addListener(function(text) { |
8 |
if(text == "color-divs") colorDivs(); |
9 |
});
|
10 |
|
11 |
// listening for an event / one-time requests
|
12 |
// coming from the popup
|
13 |
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) { |
14 |
switch(request.type) { |
15 |
case "color-divs": |
16 |
colorDivs(); |
17 |
break; |
18 |
}
|
19 |
return true; |
20 |
});
|
21 |
|
22 |
// listening for an event / long-lived connections
|
23 |
// coming from devtools
|
24 |
chrome.extension.onConnect.addListener(function (port) { |
25 |
port.onMessage.addListener(function (message) { |
26 |
switch(port.name) { |
27 |
case "color-divs-port": |
28 |
colorDivs(); |
29 |
break; |
30 |
}
|
31 |
});
|
32 |
});
|
33 |
|
34 |
// send a message to the content script
|
35 |
var colorDivs = function() { |
36 |
chrome.tabs.getSelected(null, function(tab){ |
37 |
chrome.tabs.sendMessage(tab.id, {type: "colors-div", color: "#F00"}); |
38 |
// setting a badge
|
39 |
chrome.browserAction.setBadgeText({text: "red!"}); |
40 |
});
|
41 |
}
|
Die ersten Zeilen erhalten die Aktion des Benutzers von der Omnibox. Danach setze ich einen einmaligen Anfrage-Listener, der die Nachricht von dem Browser-Aktions-Icon akzeptiert.
Das nächste Snippet ist eine langlebige Verbindung mit dem Devtools-Tab (es ist nicht unbedingt notwendig, eine langlebige Verbindung dafür zu verwenden, ich habe es nur für Bildungszwecke gemacht). Mit diesen Listenern kann ich die Eingaben des Benutzers abrufen und an das Inhaltsskript senden, das Zugriff auf die DOM-Elemente hat. Der Hauptpunkt hier war, zuerst die Registerkarte auszuwählen, die ich manipulieren wollte, und dann eine Nachricht an sie zu senden. Zuletzt habe ich ein Abzeichen auf das Erweiterungssymbol gesetzt.
Browseraktion
Wir beginnen mit unserer popup.html
Datei:
1 |
// popup.html |
2 |
<script type="text/javascript" src="popup.js"></script> |
3 |
<div style="width:200px"> |
4 |
<button id="button">Color all the divs</button> |
5 |
</div>
|
Dann erstellen wir die popup.js
Datei:
1 |
|
2 |
// popup.js
|
3 |
window.onload = function() { |
4 |
document.getElementById("button").onclick = function() { |
5 |
chrome.extension.sendMessage({ |
6 |
type: "color-divs" |
7 |
});
|
8 |
}
|
9 |
}
|
Das Pop-up enthält eine einzelne Schaltfläche. Sobald der Benutzer darauf klickt, wird eine Nachricht an das Hintergrundskript gesendet.
Entwicklerwerkzeuge
1 |
window.onload = function() { |
2 |
var port = chrome.extension.connect({ name: "color-divs-port" }); |
3 |
document.getElementById("button").onclick = function() { |
4 |
port.postMessage({ type: "color-divs"}); |
5 |
}
|
6 |
}
|
Für die DeveloperTools machen wir hier fast dasselbe wie im Pop-Up, der einzige Unterschied ist, dass ich eine langlebige Verbindung verwendet habe.
Inhaltsskript
1 |
chrome.extension.onMessage.addListener(function(message, sender, sendResponse) { |
2 |
switch(message.type) { |
3 |
case "colors-div": |
4 |
var divs = document.querySelectorAll("div"); |
5 |
if(divs.length === 0) { |
6 |
alert("There are no any divs in the page."); |
7 |
} else { |
8 |
for(var i=0; i<divs.length; i++) { |
9 |
divs[i].style.backgroundColor = message.color; |
10 |
}
|
11 |
}
|
12 |
break; |
13 |
}
|
14 |
});
|
Das Inhaltsskript wartet auf eine Nachricht, wählt alle Divs auf der aktuellen Seite aus und ändert ihre Hintergrundfarbe. Achten Sie auf das Objekt, an das ich den Hörer angeschlossen habe. In dem Inhaltsskript, das chrome.extension.onMessage
ist.
Anpassen der New Tab
Seite
Das letzte, was diese Erweiterung tut, ist die Anpassung der New Tab
Seite. Das können wir einfach tun, indem wir die Eigenschaft newtab
auf die Datei newtab/newtab.html
verweisen:
1 |
"chrome_url_overrides" : { |
2 |
"newtab": "newtab/newtab.html" |
3 |
}
|
Beachten Sie, dass Sie kein Replikat der neuen Standard new tab
Seite erstellen können. Die Idee dieser Funktion besteht darin, eine völlig andere Funktionalität hinzuzufügen. Hier ist, was Google sagt:
Versuchen Sie nicht, die Standardseite Neuer Tabulator zu emulieren. Die APIs, die erforderlich sind, um eine leicht geänderte Version der Standardseite "Neuer Tab" zu erstellen - mit Top-Seiten, kürzlich geschlossenen Seiten, Tipps, einem Hintergrundbild des Themas usw. - existieren noch nicht. Bis es so weit ist, ist es besser, etwas völlig anderes zu machen.
Debuggen
Eine Erweiterung für Google Chrome zu schreiben, ist nicht immer einfach und Sie werden wahrscheinlich einige Probleme haben. Die gute Sache ist, dass Sie immer noch die Konsole verwenden können, um Ihre Variablen auszugeben, um beim Debuggen zu helfen. Fühlen Sie sich frei, console.log
in Ihren Hintergrund oder Ihre Inhaltsskripte einzufügen. Dies funktioniert jedoch nicht in Skripten, die im Kontext der Entwicklerwerkzeuge ausgeführt werden. In diesem Fall sollten Sie die alert
-Methode verwenden, da sie überall funktioniert.
Fazit
Meiner Meinung nach ist Chrome einer der besten verfügbaren Browser. Die Entwickler bei Google machen das Erstellen von Erweiterungen relativ einfach, indem wir ihnen die Möglichkeit geben, sie in HTML, CSS und JavaScript zu erstellen.
Ja, es gibt einige knifflige Teile, aber im Allgemeinen können wir wertvolle Plugins produzieren. Beachten Sie, dass in diesem Artikel nicht alles behandelt wird, was mit der Entwicklung von Chrome-Erweiterungen zu tun hat. Es gibt einige andere nützliche Dinge wie Kontextmenüs, Optionen-Seiten und Benachrichtigungen. Für die Themen, die ich nicht behandelt habe, finden Sie in der Dokumentation für weitere Informationen.