Arbeiten mit der Tabs-API
Tabs ermöglichen es einem Benutzer, mehrere Webseiten in ihrem Browserfenster zu öffnen und zwischen diesen Webseiten zu wechseln. Mit der Tabs-API können Sie mit diesen Tabs arbeiten und sie manipulieren, um Dienste zu erstellen, die Benutzern neue Möglichkeiten zur Arbeit mit Tabs bieten oder die Funktionen Ihrer Erweiterung bereitstellen.
In diesem Leitfaden werden wir uns mit Folgendem befassen:
- Benötigte Berechtigungen zur Nutzung der Tabs-API.
- Erfahren Sie mehr über Tabs und ihre Eigenschaften mit
tabs.query
. - Erstellen, Duplizieren, Verschieben, Aktualisieren, Neuladen und Entfernen von Tabs.
- Manipulieren des Zoomfaktors eines Tabs.
- Manipulieren der CSS eines Tabs.
Zum Schluss betrachten wir einige weitere, diverse Funktionen, die die API bietet.
Hinweis:
Es gibt einige Tab-API-Funktionen, die anderswo behandelt werden. Dies sind die Methoden, die Sie verwenden können, um Tab-Inhalte mit Skripten zu manipulieren (tabs.connect
, tabs.sendMessage
und tabs.executeScript
). Wenn Sie mehr Informationen zu diesen Methoden wünschen, lesen Sie den Konzeptartikel Inhalts-Skripte und die Anleitung Eine Webseite ändern.
Berechtigungen und die Tabs-API
Für die Mehrheit der Funktionen der Tabs-API benötigen Sie keine Berechtigungen; es gibt jedoch einige Ausnahmen:
- Die Berechtigung
"tabs"
ist erforderlich, um auf die EigenschaftenTab.url
,Tab.title
undTab.favIconUrl
des Tab-Objekts zuzugreifen. In Firefox benötigen Sie auch"tabs"
, um eine Abfrage nach URL durchzuführen. - Host-Berechtigung ist nötig für
tabs.executeScript()
odertabs.insertCSS()
.
Im Folgenden sehen Sie, wie Sie die Berechtigung "tabs"
in der manifest.json-Datei Ihrer Erweiterung anfordern könnten:
"permissions": [
"<all_urls>",
"tabs"
],
Diese Anfrage ermöglicht Ihnen die Nutzung aller Funktionen der Tabs-API auf allen Websites, die Ihr Benutzer besucht. Es gibt auch einen alternativen Ansatz für die Anforderung von Berechtigungen zur Verwendung von tabs.executeScript()
oder tabs.insertCSS()
, bei dem keine Host-Berechtigung erforderlich ist, in Form von "activeTab"
. Diese Berechtigung bietet die gleichen Rechte wie "tabs"
mit <all_urls>
, aber mit zwei Einschränkungen:
- Der Benutzer muss über seine Browser- oder Seitenaktion, das Kontextmenü oder einen Shortcut-Schlüssel mit der Erweiterung interagieren.
- Sie gewährt die Berechtigung nur innerhalb des aktiven Tabs.
Der Vorteil dieses Ansatzes besteht darin, dass der Benutzer keine Berechtigungswarnung erhält, die besagt, dass Ihre Erweiterung "auf Ihre Daten für alle Websites zugreifen" kann. Dies liegt daran, dass die Berechtigung <all_urls>
einer Erweiterung die Möglichkeit gibt, zu jeder Zeit Skripte in jedem Tab auszuführen, während "activeTab"
darauf beschränkt ist, der Erweiterung zu erlauben, eine benutzerangeforderte Aktion im aktuellen Tab auszuführen.
Erfahren Sie mehr über Tabs und ihre Eigenschaften
Es wird Gelegenheiten geben, in denen Sie eine Liste aller Tabs in allen Browserfenstern erhalten möchten. Zu anderen Zeiten möchten Sie vielleicht eine Teilmenge von Tabs finden, die bestimmte Kriterien erfüllen, wie zum Beispiel diejenigen, die von einem bestimmten Tab geöffnet wurden oder Seiten von einer bestimmten Domain anzeigen. Und sobald Sie Ihre Liste von Tabs haben, möchten Sie wahrscheinlich mehr über deren Eigenschaften erfahren.
Hier kommt tabs.query()
ins Spiel. Allein verwendet, um alle Tabs zu erhalten, oder mit dem queryInfo
-Objekt, um Abfragekriterien wie ob der Tab aktiv ist, im aktuellen Fenster oder eines oder mehrere von 17 Kriterien anzugeben, gibt tabs.query()
ein Array von tabs.Tab
Objekten zurück, die Informationen über die Tabs enthalten.
Wo Sie Informationen nur über den aktuellen Tab haben möchten, können Sie ein tabs.Tab
Objekt für diesen Tab mit tabs.getCurrent()
erhalten. Wenn Sie die ID eines Tabs haben, können Sie sein tabs.Tab
Objekt mit tabs.get()
erhalten.
Anleitung
Um zu sehen, wie tabs.query()
und tabs.Tab
verwendet werden, gehen wir durch, wie das tabs-tabs-tabs Beispiel die Liste der "zu Tabs wechseln" zu seinem Toolbar-Button-Popup hinzufügt.
- manifest.json
-
Hier ist das
manifest.json
:json{ "browser_action": { "default_title": "Tabs, tabs, tabs", "default_popup": "tabs.html" }, "description": "A list of methods you can perform on a tab.", "homepage_url": "https://github.com/mdn/webextensions-examples/tree/main/tabs-tabs-tabs", "manifest_version": 2, "name": "Tabs, tabs, tabs", "permissions": ["tabs"], "version": "1.0" }
Hinweis:
tabs.html
ist alsdefault_popup
inbrowser_action
definiert. Es wird jedes Mal angezeigt, wenn der Benutzer auf das Symbol der Erweiterung in der Symbolleiste klickt.- Berechtigungen beinhalten tabs. Dies wird benötigt, um die Tab-Liste Funktion zu unterstützen, da die Erweiterung die Titel der Tabs liest, um sie im Popup anzuzeigen.
- tabs.html
-
tabs.html
definiert den Inhalt des Popups der Erweiterung:html<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="stylesheet" href="tabs.css" /> </head> <body> <div class="panel"> <div class="panel-section panel-section-header"> <div class="text-section-header">Tabs-tabs-tabs</div> </div> <a href="#" id="tabs-move-beginning"> Move active tab to the beginning of the window </a> <br /> <!-- Define the other menu items --> <div class="switch-tabs"> <p>Switch to tab</p> <div id="tabs-list"></div> </div> </div> <script src="tabs.js"></script> </body> </html>
Dies macht Folgendes:
- Die Menüelemente werden deklariert.
- Ein leerer
div
mit der IDtabs-list
wird deklariert, um die Liste der Tabs zu enthalten. tabs.js
wird aufgerufen.
- tabs.js
-
In
tabs.js
sehen wir, wie die Liste der Tabs erstellt und zum Popup hinzugefügt wird.
Das Popup erstellen
Zuerst wird ein Ereignishandler hinzugefügt, der listTabs()
ausführt, wenn tabs.html
geladen wird:
document.addEventListener("DOMContentLoaded", listTabs);
Das Erste, was listTabs()
tut, ist getCurrentWindowTabs()
aufzurufen. Dies ist, wo tabs.query()
verwendet wird, um ein tabs.Tab
Objekt für die Tabs im aktuellen Fenster zu bekommen:
function getCurrentWindowTabs() {
return browser.tabs.query({ currentWindow: true });
}
Jetzt ist listTabs()
bereit, den Inhalt für das Popup zu erstellen.
Zu Beginn:
- Erfassen Sie das
<div id="tabs-list">
Element. - Erstellen Sie ein Dokumentfragment (in das die Liste aufgebaut wird).
- Setzen Sie Zähler.
- Löschen Sie den Inhalt des
<div id="tabs-list">
Elements.
function listTabs() {
getCurrentWindowTabs().then((tabs) => {
const tabsList = document.getElementById("tabs-list");
const currentTabs = document.createDocumentFragment();
const limit = 5;
let counter = 0;
tabsList.textContent = "";
Als Nächstes erstellen wir die Links für jeden Tab:
-
Schleifen Sie durch die ersten 5 Elemente des
tabs.Tab
Objekts. -
Für jedes Element fügen Sie dem Dokumentfragment einen Hyperlink hinzu.
- Das Label des Links — das heißt, sein Text — wird mit dem
title
des Tabs (oder derid
, falls er keinentitle
hat) gesetzt. - Die Adresse des Links wird mit der
id
des Tabs gesetzt.
- Das Label des Links — das heißt, sein Text — wird mit dem
for (const tab of tabs) {
if (!tab.active && counter <= limit) {
const tabLink = document.createElement("a");
tabLink.textContent = tab.title || tab.id;
tabLink.setAttribute("href", tab.id);
tabLink.classList.add("switch-tabs");
currentTabs.appendChild(tabLink);
}
counter += 1;
}
Schließlich wird das Dokumentfragment in das <div id="tabs-list">
Element geschrieben:
tabsList.appendChild(currentTabs);
});
}
Arbeiten mit dem aktiven Tab
Ein weiteres verwandtes Beispielmerkmal ist die "Alert aktivem Tab"-Infooption, die alle tabs.Tab
Objekt-Eigenschaften für den aktiven Tab in ein Alert ausschüttet:
else if (e.target.id === "tabs-alert-info") {
callOnActiveTab((tab) => {
let props = "";
for (const item in tab) {
props += `${item} = ${tab[item]} \n`;
}
alert(props);
});
}
Wo callOnActiveTab()
das aktive Tab-Objekt findet, indem es durch die tabs.Tab
Objekte schleift und nach dem Element sucht, das auf aktiv gesetzt ist:
document.addEventListener("click", (e) => {
function callOnActiveTab(callback) {
getCurrentWindowTabs().then((tabs) => {
for (const tab of tabs) {
if (tab.active) {
callback(tab, tabs);
}
}
});
}
});
Erstellen, Duplizieren, Verschieben, Aktualisieren, Neuladen und Entfernen von Tabs
Nachdem Sie Informationen über die Tabs gesammelt haben, möchten Sie wahrscheinlich etwas mit ihnen machen — entweder um Benutzern Funktionen zum Manipulieren und Verwalten von Tabs zu bieten oder um Funktionalitäten in Ihre Erweiterung zu implementieren.
Folgende Funktionen stehen zur Verfügung:
- Erstellen eines neuen Tabs (
tabs.create()
). - Duplizieren eines Tabs (
tabs.duplicate()
). - Entfernen eines Tabs (
tabs.remove()
). - Verschieben eines Tabs (
tabs.move()
). - Aktualisieren der URL des Tabs — im Wesentlichen zu einer neuen Seite navigieren — (
tabs.update()
). - Neuladen der Tab-Seite (
tabs.reload()
).
Hinweis: Diese Funktionen erfordern alle die ID (oder IDs) des Tabs, den sie manipulieren:
Wohingegen die folgenden Funktionen auf den aktiven Tab wirken (wenn keine Tab-id
angegeben ist):
Anleitung
Das tabs-tabs-tabs Beispiel übt alle diese Funktionen aus außer der Aktualisierung der URL eines Tabs. Die Art und Weise, wie diese APIs verwendet werden, ist ähnlich, daher schauen wir uns eine der aufwendigeren Implementierungen an, nämlich die Option "Aktiven Tab an den Anfang der Fensterliste verschieben".
Aber zuerst hier eine Demonstration der Funktion in Aktion:
- manifest.json
-
Keine der Funktionen erfordert eine Berechtigung zur Ausführung, daher gibt es keine Funktionen in der manifest.json Datei, die hervorgehoben werden müssen.
- tabs.html
-
tabs.html
definiert das "Menü", das im Popup angezeigt wird, einschließlich der Option "Aktiven Tab an den Anfang der Fensterliste verschieben", mit einer Reihe von<a>
Tags, die durch einen visuellen Separator gruppiert sind. Jedes Menüpunkts-Element erhält eineid
, die intabs.js
verwendet wird, um zu bestimmen, welches Menüpunkt-Element angefordert wird.html<a href="#" id="tabs-move-beginning"> Move active tab to the beginning of the window </a> <br /> <a href="#" id="tabs-move-end">Move active tab to the end of the window</a> <br /> <div class="panel-section-separator"></div> <a href="#" id="tabs-duplicate">Duplicate active tab</a><br /> <a href="#" id="tabs-reload">Reload active tab</a><br /> <a href="#" id="tabs-alert-info">Alert active tab info</a><br />
- tabs.js
-
Um das in
tabs.html
definierte "Menü" zu implementieren, enthälttabs.js
einen Listener für Klicks intabs.html
:jsdocument.addEventListener("click", (e) => { function callOnActiveTab(callback) { getCurrentWindowTabs().then((tabs) => { for (const tab of tabs) { if (tab.active) { callback(tab, tabs); } } }); } });
Eine Reihe von
if
-Anweisungen sucht dann nach derid
des geklickten Elements.Dieses Code-Snippet ist für die Option "Aktiven Tab an den Anfang der Fensterliste verschieben":
jsif (e.target.id === "tabs-move-beginning") { callOnActiveTab((tab, tabs) => { let index = 0; if (!tab.pinned) { index = firstUnpinnedTab(tabs); } console.log(`moving ${tab.id} to ${index}`); browser.tabs.move([tab.id], { index }); }); }
Es ist erwähnenswert, die Verwendung von
console.log()
. Damit können Sie Informationen in der Debugger-Konsole ausgeben, was nützlich sein kann, um während der Entwicklung gefundene Probleme zu lösen.Der Umzug-Code ruft zuerst
callOnActiveTab()
auf, der wiederumgetCurrentWindowTabs()
aufruft, um eintabs.Tab
Objekt zu erhalten, das die Tabs des aktiven Fensters enthält. Dann schleift er durch das Objekt, um das aktive Tab-Objekt zu finden und zurückzugeben:jsfunction callOnActiveTab(callback) { getCurrentWindowTabs().then((tabs) => { for (const tab of tabs) { if (tab.active) { callback(tab, tabs); } } }); }
Angepinnte Tabs
Eine Funktion von Tabs ist, dass der Benutzer Tabs in einem Fenster anpinnen kann. Angepinnte Tabs werden am Anfang der Tab-Liste platziert und können nicht verschoben werden. Das bedeutet, dass die früheste Position, zu der ein Tab bewegt werden kann, die erste Position nach allen angehefteten Tabs ist. Daher wird firstUnpinnedTab()
aufgerufen, um die Position des ersten nicht angehefteten Tabs zu finden, indem durch das tabs
-Objekt geschleift wird:
function firstUnpinnedTab(tabs) {
for (const tab of tabs) {
if (!tab.pinned) {
return tab.index;
}
}
}
Jetzt haben wir alles, was benötigt wird, um den Tab zu verschieben: das aktive Tab-Objekt, von dem wir die Tab-id
und die Position, an die der Tab verschoben werden soll, bekommen. Also können wir den Umzug implementieren:
browser.tabs.move([tab.id], { index });
Die verbleibenden Funktionen zum Duplizieren, Neuladen, Erstellen und Entfernen von Tabs werden auf ähnliche Weise implementiert.
Manipulation des Zoomfaktors eines Tabs
Die nächste Reihe von Funktionen ermöglicht es Ihnen, den Zoomfaktor innerhalb eines Tabs zu erhalten (tabs.getZoom
) und zu setzen (tabs.setZoom
). Sie können auch die Zoomeinstellungen abrufen (tabs.getZoomSettings
), aber zum Zeitpunkt des Schreibens war die Möglichkeit, die Einstellungen zu setzen (tabs.setZoomSettings
) in Firefox nicht verfügbar.
Der Zoomfaktor kann zwischen 30 % und 500 % liegen (dargestellt als Dezimalwerte 0.3
bis 5
).
In Firefox sind die Standard-Zoomeinstellungen:
- Standard-Zoomfaktor: 100 %.
- Zoommodus: automatisch (damit verwaltet der Browser, wie Zoomstufen gesetzt werden).
- Reichweite der Zoomänderungen:
"per-origin"
, was bedeutet, dass wenn Sie eine Seite erneut besuchen, es die Zoomstufe übernimmt, die bei Ihrem letzten Besuch eingestellt war.
Anleitung
Das tabs-tabs-tabs Beispiel umfasst drei Demonstrationen der Zoomfunktion: Zoomen, Herauszoomen und Zoom zurücksetzen. Hier ist das Feature in Aktion:
Schauen wir uns an, wie das Zoomen implementiert ist.
- manifest.json
-
Keine der Zoomfunktionen erfordert Berechtigungen, daher gibt es keine Funktionen in der manifest.json Datei, die hervorgehoben werden müssen.
- tabs.html
-
Wir haben bereits besprochen, wie das
tabs.html
die Optionen für diese Erweiterung definiert, nichts Neues oder Einzigartiges wird gemacht, um die Zoomoptionen bereitzustellen. - tabs.js
-
tabs.js
beginnt mit der Definition mehrerer Konstanten, die im Zoom-Code verwendet werden:jsconst ZOOM_INCREMENT = 0.2; const MAX_ZOOM = 5; const MIN_ZOOM = 0.3; const DEFAULT_ZOOM = 1;
Es verwendet dann denselben Listener, den wir bereits besprochen haben, damit es auf Klicks in
tabs.html
reagieren kann.Für die Vergrößerung führt dies:
jselse if (e.target.id === "tabs-add-zoom") { callOnActiveTab((tab) => { browser.tabs.getZoom(tab.id).then((zoomFactor) => { // The maximum zoomFactor is 5, it can't go higher if (zoomFactor >= MAX_ZOOM) { alert("Tab zoom factor is already at max!"); } else { let newZoomFactor = zoomFactor + ZOOM_INCREMENT; // If the newZoomFactor is set to higher than the max accepted // it won't change, and will never alert that it's at maximum newZoomFactor = newZoomFactor > MAX_ZOOM ? MAX_ZOOM : newZoomFactor; browser.tabs.setZoom(tab.id, newZoomFactor); } }); }); }
Dieser Code verwendet
callOnActiveTab()
, um die Details des aktiven Tabs zu erhalten, dann erhälttabs.getZoom
den aktuellen Zoomfaktor des Tabs. Der aktuelle Zoom wird mit dem definierten Maximum (MAX_ZOOM
) verglichen und es wird eine Warnung ausgegeben, wenn der Tab bereits beim maximalen Zoom ist. Andernfalls wird der Zoomfaktor inkrementiert, aber auf den maximalen Zoom beschränkt, dann wird der Zoom mittabs.getZoom
gesetzt.
Manipulation der CSS eines Tabs
Eine andere wesentliche Fähigkeit, die die Tabs-API bietet, ist die Möglichkeit, das CSS innerhalb eines Tabs zu manipulieren — fügen Sie einem Tab neues CSS hinzu (tabs.insertCSS()
) oder entfernen Sie CSS von einem Tab (tabs.removeCSS()
).
Dies kann nützlich sein, zum Beispiel, wenn Sie bestimmte Seitenelemente hervorheben oder das Standardlayout der Seite ändern möchten.
Anleitung
Das apply-css Beispiel verwendet diese Funktionen, um der Webseite im aktiven Tab einen roten Rahmen hinzuzufügen. Hier ist das Feature in Aktion:
Lassen Sie uns durchgehen, wie es eingerichtet ist.
- manifest.json
-
Die
manifest.json
fordert Berechtigungen an, die erforderlich sind, um die CSS-Funktionen zu verwenden. Sie benötigen entweder:"tabs"
Berechtigung und Host-Berechtigung; oder,"activeTab"
Berechtigung.
Letzteres ist am nützlichsten, da es einer Erweiterung erlaubt,
tabs.insertCSS()
undtabs.removeCSS()
im aktiven Tab zu verwenden, wenn sie von der Browser- oder Seitenaktion der Erweiterung, dem Kontextmenü oder einem Shortcut ausgeführt wird.json{ "description": "Adds a page action to toggle applying CSS to pages.", "manifest_version": 2, "name": "apply-css", "version": "1.0", "homepage_url": "https://github.com/mdn/webextensions-examples/tree/main/apply-css", "background": { "scripts": ["background.js"] }, "page_action": { "default_icon": "icons/off.svg" }, "permissions": ["activeTab", "tabs"] }
Sie werden feststellen, dass
"tabs"
Berechtigung zusätzlich zu"activeTab"
angefordert wird. Diese zusätzliche Berechtigung ist nötig, um dem Skript der Erweiterung den Zugriff auf die URL des Tabs zu ermöglichen, dessen Bedeutung wir in einem Moment sehen werden.Die anderen Hauptmerkmale in der manifest.json Datei sind die Definition von:
- einem Hintergrundskript, das gestartet wird, sobald die Erweiterung geladen ist.
- einer "Seitenaktion", die ein Symbol definiert, das zur Adressleiste des Browsers hinzugefügt wird.
- background.js
-
Beim Start setzt
background.js
einige Konstanten, um das anzuwendende CSS zu definieren, Titel für die "Seitenaktion" und eine Liste von Protokollen, mit denen die Erweiterung arbeiten wird:jsconst CSS = "body { border: 20px solid red; }"; const TITLE_APPLY = "Apply CSS"; const TITLE_REMOVE = "Remove CSS"; const APPLICABLE_PROTOCOLS = ["http:", "https:"];
Wenn die Erweiterung zuerst geladen wird, verwendet sie
tabs.query()
, um eine Liste aller Tabs im aktuellen Browserfenster zu erhalten. Es schleift dann durch die Tabs und ruftinitializePageAction()
auf.jsbrowser.tabs.query({}).then((tabs) => { for (const tab of tabs) { initializePageAction(tab); } });
initializePageAction
verwendetprotocolIsApplicable()
, um festzustellen, ob die URL des aktiven Tabs eine ist, auf die das CSS angewendet werden kann:jsfunction protocolIsApplicable(url) { const anchor = document.createElement("a"); anchor.href = url; return APPLICABLE_PROTOCOLS.includes(anchor.protocol); }
Wenn das Beispiel dann auf den Tab wirken kann, setzt
initializePageAction()
daspageAction
(Navigationsleisten)-Symbol und den Titel des Tabs zu den "Off"-Versionen, bevor es diepageAction
sichtbar macht:jsfunction initializePageAction(tab) { if (protocolIsApplicable(tab.url)) { browser.pageAction.setIcon({ tabId: tab.id, path: "icons/off.svg" }); browser.pageAction.setTitle({ tabId: tab.id, title: TITLE_APPLY }); browser.pageAction.show(tab.id); } }
Als Nächstes wartet ein Listener auf
pageAction.onClicked
darauf, dass daspageAction
Symbol geklickt wird, und rufttoggleCSS
auf, wenn es das ist.jsbrowser.pageAction.onClicked.addListener(toggleCSS);
toggleCSS()
holt den Titel derpageAction
und führt dann die beschriebene Aktion aus:-
Für "CSS anwenden":
- wechselt das
pageAction
Symbol und den Titel zu den "Entfernen"-Versionen. - wendet das CSS mit
tabs.insertCSS()
an.
- wechselt das
-
Für "CSS entfernen":
- wechselt das
pageAction
Symbol und den Titel zu den "Anwenden"-Versionen. - entfernt das CSS mit
tabs.removeCSS()
.
- wechselt das
jsfunction toggleCSS(tab) { function gotTitle(title) { if (title === TITLE_APPLY) { browser.pageAction.setIcon({ tabId: tab.id, path: "icons/on.svg" }); browser.pageAction.setTitle({ tabId: tab.id, title: TITLE_REMOVE }); browser.tabs.insertCSS({ code: CSS }); } else { browser.pageAction.setIcon({ tabId: tab.id, path: "icons/off.svg" }); browser.pageAction.setTitle({ tabId: tab.id, title: TITLE_APPLY }); browser.tabs.removeCSS({ code: CSS }); } } browser.pageAction.getTitle({ tabId: tab.id }).then(gotTitle); }
Schließlich, um sicherzustellen, dass die
pageAction
nach jedem Aktualisieren des Tabs gültig ist, ruft ein Listener auftabs.onUpdated
initializePageAction()
jedes Mal auf, wenn der Tab aktualisiert wird, um zu prüfen, ob der Tab noch ein Protokoll verwendet, auf das das CSS angewendet werden kann.jsbrowser.tabs.onUpdated.addListener((id, changeInfo, tab) => { initializePageAction(tab); });
-
Einige andere interessante Fähigkeiten
Es gibt noch ein paar andere Funktionen der Tabs-API, die in keine der vorherigen Abschnitte passen:
- Erfassen Sie den sichtbaren Tab-Inhalt mit
tabs.captureVisibleTab
. - Erkennen Sie die Hauptsprache der Inhalte in einem Tab mit
tabs.detectLanguage
. Dies könnte zum Beispiel verwendet werden, um die Sprache im Benutzerinterface Ihrer Erweiterung mit der der Seite, auf der sie ausgeführt wird, abzustimmen.
Erfahren Sie mehr
Wenn Sie mehr über die Tabs-API erfahren möchten, lesen Sie:
- Tabs-API-Referenz
- Beispiel-Erweiterungen (von denen viele die Tabs-API verwenden)