[译]Chrome开发第1部分:扩展
By robot-v1.0
本文链接 https://www.kyfws.com/applications/chrome-development-part-extensions-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 37 分钟阅读 - 18526 个词 阅读量 0[译]Chrome开发第1部分:扩展
原文地址:https://www.codeproject.com/Articles/1103565/Chrome-Development-Part-Extensions
原文作者:Matt Scarpino
译文由本站 robot-v1.0 翻译
前言
This article explains how to code extensions that customize, access, and augment the capabilities of the Chrome browser. 本文介绍了如何对扩展程序进行编码,以自定义,访问和增强Chrome浏览器的功能.
1.简介(1. Introduction)
根据(According to) W3Counter(W3Counter) ,Chrome是世界上最受欢迎的浏览器.许多人使用它来访问网站,但是很少有人知道如何使用扩展来扩展其功能.扩展程序提供了许多令人兴奋的功能,例如自定义Chrome的外观,与当前页面进行交互或向浏览器外部的应用程序发送消息.(, Chrome is the most popular browser in the world. Many use it to visit web sites, but few know how to extend its features with extensions. Extensions provide a wealth of exciting capabilities, such as customizing Chrome’s appearance, interacting with the current page, or sending messages to applications outside the browser.) 本文探讨了用于开发Chrome扩展程序的Google API. JavaScript是此讨论的核心,因此在继续之前,您应该对这种语言有充分的了解.的(This article explores Google’s API for developing Chrome extensions. JavaScript is central to this discussion, so before proceeding, you should have a solid familiarity with the language. The) 第二篇(second article) 本系列中的内容介绍了如何对Chrome应用进行编码.(in the series explains how to code Chrome apps.)
2. Chrome扩展程序概述(2. Overview of Chrome Extensions)
Chrome扩展程序是一个压缩文件夹,其文件可配置Chrome的行为或外观.有三点要理解:(A Chrome extension is a zipped folder whose files configure Chrome’s behavior or appearance. There are three important points to understand:)
- 每个扩展名必须具有一个名为manifest.json的文件.它描述了扩展程序的功能,并确定了扩展程序与浏览器的交互方式.(Every extension must have a file named manifest.json. This describes the extension’s capabilities and identifies how it interacts with the browser.)
- 扩展程序的行为由JavaScript文件配置,有两种类型.一种(An extension’s behavior is configured with JavaScript files, which come in two types. A)**后台脚本(background script)**可以访问Chrome的所有功能,但不能与浏览器的文档进行交互.一种(can access all of Chrome’s capabilities, but can’t interact with the browser’s document. A)**内容脚本(content script)**可以读取或修改浏览器的文档,但只能访问Chrome的有限功能.(can read or modify the browser’s document, but can only access a limited set of Chrome’s capabilities.)
- 在Chrome浏览器访问扩展程序之前,必须将该文件夹压缩到一个名为* .crx文件的特殊存档中.然后必须将其加载到浏览器中.(*Before Chrome can access an extension, the folder must be zipped into a special archive called a *.crx file. Then it must be loaded into the browser.*) 本节首先讨论manifest.json的格式.然后,它介绍了一个简单的扩展程序,并说明了如何将其加载到Chrome中.(*This section starts by discussing the format of manifest.json. Then it introduces a simple extension and explains how to load it into Chrome.*)
2.1扩展清单(2.1 The Extension Manifest)
manifest.json的格式基于JavaScript对象表示法(JSON).它定义了一对花括号内的属性列表.可以将许多不同的属性添加到manifest.json,您可以看到完整列表(The format of manifest.json is based on JavaScript Object Notation (JSON). It defines of a list of properties inside a pair of curly braces. Many different properties can be added to manifest.json, and you can see the full list) 这里(here) .只需要三个:(. Only three are required:)
-
manifest_version
—清单格式的版本应设置为(— The version of the manifest format, should be set to)2
-
name
—标识扩展名的字符串(— A string that identifies the extension’s name) -
version
—标识扩展版本的字符串(— A string that identifies the extension’s version) 为了进一步描述扩展,建议使用两个属性:(To further describe the extension, two properties are recommended:) -
description
—描述扩展的字符串(— A string that describes the extension) -
icons
—代表扩展名的一幅或多幅图像(— One or more images that represent the extension) 以下JSON显示了基本清单的外观:(The following JSON shows what a basic manifest looks like:)
{
"manifest_version": 2,
"name": "Trivial extension example",
"version": "1.0",
"description": "This extension doesn't do anything",
"icons": { "16": "images/smiley_sm.png",
"48": "images/smiley_med.png",
"128": "images/smiley_lg.png" }
}
的(The) icons
属性需要说明.根据Google的建议,每个扩展程序应至少提供三张图片:(property requires explanation. According to Google’s recommendations, every extension should provide at least three images:)
- 128x128图片-在安装过程中和由Google Web Store显示.(128x128 image — displayed during installation and by the Google Web Store.)
- 48x48图片-显示在Chrome开发人员信息中心中(48x48 image — displayed in the Chrome Developer Dashboard)
- 16x16图片-显示为扩展页面的图标(16x16 image — displayed as a favicon for the extension’s pages)
在示例清单中,(In the example manifest,)
icons
具有三个属性.每个都关联一个图像尺寸((has three properties. Each associates an image dimension ()128
,(,)48
, 要么(, or)16
)和图片文件.示例图片均为PNG,但Chrome浏览器还支持BMP,GIF,ICO和JPEG格式.() with an image file. The example images are all PNGs, but Chrome also supports the BMP, GIF, ICO, and JPEG formats.) 非平凡的扩展名必须定义其他属性.表1列出了十个属性及其用途.(Nontrivial extensions must define additional properties. Table 1 lists ten properties and their purposes.)
表1:Chrome扩展程序清单的可选属性(摘要)(Table 1: Optional Properties of a Chrome Extension Manifest (Abridged))
领域(Field) | 目的(Purpose) |
---|---|
content_scripts |
定义内容脚本(Defines a content script) |
background |
定义背景脚本(Defines a background script) |
permissions |
标识扩展可用的权限(Identifies permissions available to the extension) |
browser_action |
定义浏览器动作(Defines a browser action) |
page_action |
定义页面动作(Defines a page action) |
chrome_settings_overrides |
覆盖Chrome浏览器的设置(Overrides settings of the Chrome browser) |
chrome_ui_overrides |
覆盖Chrome用户界面的各个方面(Overrides aspects of the Chrome user interface) |
content_security_policy |
定义与扩展内容相关的规则(Defines rules related to the extension’s content) |
externally_connectable |
可以连接到扩展程序的扩展程序和应用(Extensions and apps that can connect to the extension) |
storage |
分配回调函数以写入接收到的数据(Assign callback function for writing received data) |
其中一些标识资源定义了扩展的行为,例如(Some of these identify resources that define the extension’s behavior, such as) content_scripts
和(and) background
.其他提供的设置可配置扩展程序的属性,例如(. Others provide settings that configure the extension’s properties, such as) permissions
和(and) chrome_settings_overrides
.本文讨论了这些属性的子集,包括(. This article discusses a subset of these properties, including) content_scripts
,(,) background
,(,) permissions
,(,) browser_action
和(, and) page_action
.(.)
2.2加载扩展(2.2 Loading Extensions)
Chrome使您可以轻松地将新的扩展程序加载到浏览器中.扩展程序是通过Chrome开发人员信息中心管理的,可以通过在Chrome浏览器中访问chrome://extensions来访问.仪表板的右上方有一个复选框,名为(Chrome makes it easy to load new extensions into the browser. Extensions are managed through the Chrome Developer Dashboard, which can be reached by visiting chrome://extensions in a Chrome browser. The upper-right of the dashboard has a checkbox called)开发者模式(Developer Mode)图1显示了选中后的仪表板外观.(and Figure 1 shows what the dashboard looks like when it’s checked.)
图1:处于开发人员模式的Chrome开发人员信息中心(Figure 1: The Chrome Developer Dashboard in Developer Mode)
在左侧,(On the left, the)加载解压的扩展程序…(Load unpacked extension…)按钮可以选择一个解压缩的文件夹并将扩展程序加载到Chrome中.理解加载过程的最佳方法是逐步了解一个基本示例.(button makes it possible to select an unzipped folder and load the extension into Chrome. The best way to understand the loading process is to walk through a basic example.) 本文所附的example_code.zip归档文件包含一个名为basic_demo的文件夹,该文件夹包含一个简单的manifest.json文件和图像文件.可以通过以下四个步骤将此扩展程序加载到Chrome中:(The example_code.zip archive attached to this article contains a folder called basic_demo, which consists of a simple manifest.json file and image files. This extension can be loaded into Chrome by following four steps:)
- 下载example_code.zip并解压缩存档.(Download example_code.zip and decompress the archive.)
- 在Chrome中,通过导航至chrome://extensions打开Chrome开发人员信息中心.(In Chrome, open the Chrome Developer Dashboard by navigating to chrome://extensions.)
- 按下(Press the)加载解压的扩展程序…(Load unpacked extension…)按钮,然后在解压缩的存档中选择basic_demo文件夹.(button and select the basic_demo folder in the decompressed archive.)
- 按确定以加载扩展.(Press OK to load the extension.) 加载扩展后,条目将添加到仪表板的扩展列表中.图2显示了新条目的外观.(When the extension is loaded, an entry will be added to the dashboard’s list of extensions. Figure 2 shows what the new entry looks like.)
图2:Chrome开发人员信息中心中的新条目(Figure 2: New Entry in the Chrome Developer Dashboard)
的(The)重装(Reload)链接特别有用.扩展名的文件更改后,单击此链接将自动使用更新的文件重新加载扩展名.(link is particularly helpful. After an extension’s files have changed, clicking this link automatically reloads the extension with the updated files.)
2.3包装扩展(2.3 Packaging Extensions)
许多开发人员可以通过(Many developers make their extensions available to others through the) Chrome网上应用店(Chrome Web Store) .这要求将该扩展打包为一个称为* .crx文件的签名存档.这可以通过单击(*. This requires packaging the extension as a signed archive called a *.crx file. This can be accomplished by clicking the*)包装扩展…(*Pack Extension…*)仪表板上的按钮(请参见图1). Chrome打包扩展程序时,会创建两个文件:一个包含扩展名的* .crx文件和一个包含私钥的* .pem文件.当您要更新打包的扩展程序或将其上传到Chrome网上应用店时,需要此密钥.(*button in the dashboard (see Figure 1). When Chrome packages an extension, it creates two files: a *.crx file containing the extension and a *.pem file containing the private key. This key is required when you want to update the packaged extension or upload it to the Chrome Web Store.*) 如果扩展程序已打包,则无法通过单击(*If an extension has been packaged, it can’t be updated by clicking the*)重装(*Reload*)链接.相反,您需要增加扩展的版本并重新打包扩展.提供扩展包装的完整讨论(*link. Instead, you need to increment the extension’s version and repackage the extension. A full discussion of extension packaging is available*) 这里(here) .(*.*)
3.扩展脚本(3. Extension Scripts)
如前所述,Chrome扩展程序可能包含定义其行为的JavaScript文件.这些有两种类型:内容脚本和后台脚本.本节讨论两种类型的脚本.(As mentioned earlier, a Chrome extension may contain JavaScript files that define its behavior. These come in two types: content scripts and background scripts. This section discusses both types of scripts.)
如果manifest.json将一个或多个文件与(If manifest.json associates one or more files with the) content_scripts
属性,文件是内容脚本.它们可以访问浏览器的文档,但只能使用API功能的一部分.内容脚本在浏览器页面每次更改时执行.(property, the files are content scripts. These can access the browser’s document but can only use a subset of the API’s capabilities. Content scripts execute every time the browser’s page changes.)
如果manifest.json将一个或多个文件与(If manifest.json associates one or more files with the) background
属性,这些文件是后台脚本.这些脚本可以访问Chrome扩展程序API提供的所有功能,但不能访问在浏览器中打开的文档.通常,后台脚本中的代码仅在响应选定事件时执行.(property, the files are background scripts. These scripts can access all capabilities provided by the Chrome Extension API, but they can’t access the document open in the browser. In general, the code in a background script only executes in response to selected events.)
3.1内容脚本(3.1 Content Scripts)
在manifest.json中,(Inside manifest.json,) content_scripts
可以与对象数组关联.每个对象都包含一系列属性,其中包括:(can be& associated with an array of objects. Each object contains a series of properties including the following:)
matches
—网址格式数组或(— an array of URL patterns or)<all_urls>
js
—当浏览器的URL与其中一种模式匹配时要注入的JavaScript文件数组(— an array of JavaScript files to be injected when the browser’s URL matches one of the patterns)css
—当浏览器的URL与其中一种模式匹配时要注入的CSS文件的数组(— an array of CSS files to be injected when the browser’s URL matches one of the patterns)all_frames
—标识是否应将脚本注入页面的顶部框架或所有框架(— identifies if the scripts should be injected in the top frame or all frames in the page) 例如,以下manifest.json指出,每当浏览器打开以http://www.google.com开头的页面时,都应注入scripts/jquery-2.2.4.min.js和scripts/contentscript.js:(For example, the following manifest.json states that scripts/jquery-2.2.4.min.js and scripts/contentscript.js should be injected whenever the browser opens a page starting with http://www.google.com:)
{
...
"content_scripts": [
{
"matches": ["http://www.google.com/*"],
"js": ["scripts/jquery-2.2.4.min.js", "scripts/contentscript.js"]
}
]
}
将按列出的顺序注入JavaScript文件,这意味着contentscript.js可以从jQuery访问功能. jQuery的完整描述超出了本文的范围,但是(The JavaScript files are injected in the listed order, which means contentscript.js can access features from jQuery. A full description of jQuery is beyond the scope of this article, but) 这个网站(this site) 提供适当的介绍.(provides a proper introduction.) 要查看内容脚本的工作方式,假设将以下代码插入到contentscript.js中:(To see how content scripts work, suppose that the following code is inserted into contentscript.js:)
$(document).ready(function() {
alert($(document).find("title").text());
});
如果该扩展程序已加载到Chrome中,则每当页面的URL与清单文件中的模式匹配时,浏览器就会显示一个警告框,显示当前页面的标题.(If the extension is loaded into Chrome, the browser will display an alert box displaying the title of the current page whenever the page’s URL matches a pattern in the manifest’s) matches
属性.(property.)
内容脚本无法读取或修改当前页面中的JavaScript变量/函数,并且它们无法访问Chrome的许多功能.但是他们可以使用四个API访问一组有限的功能:(Content scripts can’t read or modify the JavaScript variables/functions in the current page and they can’t access many of Chrome’s features. But they can access a limited set of functions in four APIs:) chrome.i18n
,(,) chrome.extension
,(,) chrome.runtime
和(, and) chrome.storage
.以下讨论探讨了内容脚本可用的两种功能:获取扩展信息和访问本地存储.(. The following discussion explores two capabilities available to content scripts: obtaining extension information and accessing local storage.)
3.1.1获取扩展信息(3.1.1 Obtaining Extension Information)
Chrome扩展程序中的脚本可以通过顶级属性访问浏览器及其功能(Scripts in a Chrome extension can access the browser and its capabilities through properties of a top-level) chrome
目的.这些包括(object. These include) chrome.bookmarks
,(,) chrome.tabs
和(, and) chrome.cookies
.(.) chrome
的字段通常称为API,并且可以找到API的完整列表(’s fields are generally referred to as APIs and the full list of APIs can be found) 这里(here) .(.)
最重要的API之一是(One of the most important APIs is) chrome.runtime
,从而可以响应事件并获取扩展信息.内容脚本无法访问的所有功能(, which makes it possible to respond to events and obtain extension information. A content script can’t access all the features of) chrome.runtime
,但可以获得有关其扩展名的信息.表2列出了(, but it can obtain information about its extension. Table 2 lists the properties of) chrome.runtime
使之成为可能:(that make this possible:)
表2:内容脚本chrome.runtime的信息属性(Table 2: Information Properties of chrome.runtime for Content Scripts)
属性(Property) | 信息(Information) |
---|---|
id |
扩展的唯一标识符(The extension’s unique identifier) |
getManifest() |
返回一个包含manifest.json内容的字符串(Returns a string containing the content of manifest.json) |
getURL(String path) |
将路径转换为扩展名内的完整URL(Converts the path to a full URL inside the extension) |
如图1所示,Chrome为每个扩展名分配了唯一的字符串标识符.的(As shown in Figure 1, Chrome assigns a unique string identifier to each of its extensions. The) id
现场(field of) chrome.runtime
提供此标识符作为字符串.(provides this identifier as a string.)
通常,扩展程序的URL为chrome-extension://(In general, an extension’s URL is chrome-extension://)ID(id),在哪里(, where)**ID(id)**是扩展名的唯一标识符.如果内容脚本的扩展名中需要文件或文件夹的完整URL,(is the extension’s unique identifier. If a content script needs a full URL for a file or folder in its extension,) getURL
可以使用文件或文件夹的相对路径来调用.例如,(can be called with the relative path for the file or folder. For example,) getURL("images")
返回chrome-extension://(returns chrome-extension://)ID(id)/图片.(/images.)
3.1.2本地存储访问(3.1.2 Local Storage Access)
的(The) chrome.storage
API使扩展能够在客户端计算机上加载和存储数据.使用此API时,需要注意四点:(API enables an extension to load and store data on the client’s computer. When using this API, there are four points to be aware of:)
- 要使用API,扩展名的清单必须具有其(To use the API, the extension’s manifest must have its)
permissions
字段设置为包含字符串的数组(field set to an array containing the string)"storage"
.(.) - 数据存储在未加密的数据库文件中,因此此API不适合机密信息.(Data is stored in an unencrypted database file, so this API isn’t suitable for confidential information.)
- 脚本可以通过调用以下函数来加载和存储数据:(A script can load and store data by calling functions of a)
StorageArea
目的.(object.) - 三种(Three types of)
StorageArea
可用:(s are available:)chrome.sync
,(,)chrome.local
和(, and)chrome.managed
.(.) 如第三点所述,要知道的中心对象是(As stated in the third point, the central object to know is)StorageArea
.表3列出了此对象提供的五个功能.(. Table 3 lists the five functions provided by this object.)
表3:StorageArea功能(Table 3: StorageArea Functions)
功能(Function) | 描述(Description) |
---|---|
set(Object items, Function callback) |
存储给定的项目(Stores the given items) |
get(String|String[]|Object keys, |
|
Function callback) |
返回由一个或多个键标识的数据(Returns the data identified by the key/keys) |
getBytesInUse(String|String[] keys, |
|
Function callback) |
返回所需的字节数(Returns the number of bytes needed to) |
存储由一个或多个键标识的数据(store the data identified by the key/keys) | |
remove(String|String[] keys, function) |
删除由一个或多个键标识的项目(Removes the items identified by the key/keys) |
clear(Function callback) |
删除存储中的所有项目(Removes all items in storage) |
与常规数据库一样,(As with a regular database, the data in a) StorageArea
使用键值对加载和存储.以下代码存储键值为的键值对(is loaded and stored using key-value pairs. The following code stores a key-value pair whose key is) browser
其值是(and whose value is) chrome
:(:)
chrome.storage.local.set({"browser": "chrome"}, function() {
console.log("Data stored");
});
在致电给(In the call to) set
,第一个参数定义要存储的数据.第二个参数定义操作完成时要调用的函数.全部(, the first argument defines the data to be stored. The second argument defines a function to be called when the operation is complete. All of the) StorageArea
函数接受回调函数作为参数,但是仅对于(functions accept callback functions as arguments, but they’re only required for) get
和(and) getBytesInUse
.以下代码演示了如何(. The following code demonstrates how) get
可以调用以访问与键关联的值,(can be called to access the value associated with the key,) browser
.(.)
chrome.storage.local.get("browser", function(data) {
console.log("Result: " + data.browser);
});
读取操作完成后,回调函数将设置(When the read operation is complete, the callback function sets the)数据(data)等于接收到的对象的变量,并以(variable equal to the received object and accesses the value as) pair.browser
.(.)
前面的示例通过访问执行加载/存储操作(The preceding examples performed load/store operations by accessing) storage.local
.这是三个之一(. This is one of three) StorageArea
可以访问的:(s that can be accessed:)
storage.local
—提供多达5,242,880字节的存储.只能在本地设备上访问.(— Provides up to 5,242,880 bytes of storage. Can only be accessed on the local device.)storage.sync
—提供最多102,400字节的存储(最多512个项目,每个8,192字节).如果启用了Chrome同步,则用户可以在任何运行Chrome的设备上访问此数据.(— Provides up to 102,400 bytes of storage (a maximum of 512 items of 8,192 bytes each). If Chrome Sync is enabled, the user can access this data on any device running Chrome.)storage.managed
—项目由域管理员设置.该区域对于扩展名是只读的.(— Items are set by the domain administrator. This area is read-only for extensions.) 尽管内存大小有限,(Although the memory size is limited,)storage.sync
对于在多台设备上运行Chrome的用户来说非常方便.可以通过转到设置,使用Google帐户登录并选择应同步的数据类型来启用Chrome Sync.如果未启用Chrome同步,(is convenient for users running Chrome on multiple devices. Chrome Sync can be enabled by going to Settings, logging in with a Google account, and selecting the type of data that should be synchronized. If Chrome Sync isn’t enabled,)storage.sync
像(works like)storage.local
.(.)
3.2后台脚本(3.2 Background Scripts)
顾名思义,后台脚本在后台运行并响应事件.默认情况下,这些脚本会在扩展程序启动时加载,并且只要扩展程序运行它们就会占用资源.但是可以将后台脚本配置为仅在需要时才加载.这是通过设置(As its name implies, a background script runs in the background and responds to events. By default, these scripts are loaded when the extension starts and they occupy resources as long as the extension runs. But a background script can be configured to be loaded only when it’s needed. This is accomplished by setting the) persistent
的属性(property of the) background
财产(property to) false
. manifest.json中的以下声明显示了如何配置它:(. The following declaration in manifest.json shows how this can be configured:)
"background": {
"scripts": ["bground.js"],
"persistent": false
}
与内容脚本不同,后台脚本可以访问Chrome API的所有功能.本节探讨了三个重要功能:事件处理,选项卡访问和消息传递.(Unlike content scripts, a background script can access all the features of the Chrome API. This section explores three important capabilities: event handling, tab access, and message passing.)
3.2.1事件处理(3.2.1 Event Handling)
正如JavaScript可以响应用户事件一样,(Just as JavaScript makes it possible to respond to user events, the) chrome.runtime
API使响应与扩展程序和Chrome浏览器有关的事件成为可能.其中包括扩展程序的安装,执行和卸载.(API makes it possible to respond to events related to the extension and the Chrome browser. These include the extension’s installation, execution, and unloading.)
后台脚本可以通过以下属性响应这些事件(A background script can respond to these events through properties of) chrome.runtime
.表4列出了其中的五个以及触发其事件的事件.(. Table 4 lists five of them and the occurrences that trigger their events.)
表4:chrome.runtime事件(摘要)(Table 4: Events of chrome.runtime (Abridged))
事件(Event) | 触发(Trigger) |
---|---|
onStartup |
每次扩展开始执行时触发(Fires each time the extension begins executing) |
onInstalled |
在安装或更新扩展程序或Chrome时触发(Fires when the extension or Chrome is installed or updated) |
onSuspend |
在扩展程序卸载之前触发(Fires just before the extension is unloaded) |
onSuspendCancelled |
取消扩展的卸载时触发(Fires when the extension’s unloading is cancelled) |
onUpdateAvailable |
有扩展名更新可用时触发(Fires when an update to the extension is available) |
每个都有一个(Each of these has an) addListener
接受回调函数的函数.发生相应事件时将调用此功能.大多数回调不接受任何参数,但与(function that accepts a callback function. This function will be invoked when the corresponding event occurs. Most callbacks don’t accept any parameters, but the callback associated with) onInstalled
接收具有三个属性的对象:(receives an object with three properties:)
reason
—安装事件的原因.可以设置为(— The cause of the installation event. This may be set to)"install"
,(,)"update"
,(,)"chrome_update"
, 要么(, or)"shared_module_update"
.(.)previousVersion
—一个字符串,用于标识安装/更新之前的版本(— a string that identifies the version before the installation/update)id
—共享模块的标识符(如果共享模块已更新)(— the identifier of the shared module if a shared module was updated) 例如,后台脚本中的以下代码记录了安装事件的原因:(As an example, the following code in a background script logs the reason for the installation event:)
chrome.runtime.onInstalled.addListener(function(obj) {
console.log("Installation event: " + obj.reason);
});
如果后台脚本执行此代码,则该消息将不会打印在当前网页的控制台上.扩展程序的后台脚本在一个特殊的页面中运行,可以通过进入Chrome开发人员仪表板进行访问.点击(If a background script executes this code, the message won’t be printed in the console of the current web page. An extension’s background scripts run in a special page that can be accessed by going to the Chrome Developer Dashboard. Clicking the)背景链接(background link)在仪表板上,将打开背景页面.(in the dashboard opens the background page.)
重要的是要了解(It’s important to see the difference between) onUpdateAvailable
和(and) onInstalled
.如果该扩展程序有可用更新,但由于该扩展程序正在运行而无法安装,则(. If an update for the extension is available but it can’t be installed because the extension is running, an) onUpdateAvailable
事件将被触发.如果有可用更新并且可以安装,(event will be triggered. If an update is available and can be installed, an) onInstalled
扩展程序更新后将触发事件.(event will be triggered after the extension is updated.)
3.2.2选项卡(3.2.2 Tabs)
的(The) chrome.tabs
API提供了用于在浏览器中创建,修改和删除标签的多种功能.表5列出了五个有用的功能,并对每个功能进行了简短描述.(API provides a variety of functions for creating, modifying, and removing tabs in a browser. Table 5 lists five helpful functions and provides a short description of each.)
表5:chrome.tabs的功能(节略)(Table 5: Functions of chrome.tabs (Abridged))
功能(Function) | 描述(Description) |
---|---|
query(Object queryInfo, |
|
Function callback) |
提供一个或多个符合指定条件的标签(Provides one or more tabs that meet the given criteria) |
update(Integer id, |
|
Object updateProps, |
|
Function callback) |
使用给定的ID修改选项卡的属性(Modifies the properties of the tab with the given ID) |
create(Object createProps, |
|
Function callback) |
在浏览器中创建一个新标签(Creates a new tab in the browser) |
remove(Integer|Integer[] id, |
|
Function callback) |
从窗口中删除一个或多个选项卡(Removes one or more tabs from the window) |
executeScript(Integer id, |
|
Object details, |
|
Function callback) |
在给定标签中注入JavaScript代码或CSS(Injects JavaScript code or CSS in the given tab) |
的(The) query
功能提供一个或多个(function provides one or more) Tab
与选项卡相对应的对象在浏览器窗口中打开.它的第一个参数定义了一组用于选择选项卡的条件,第二个参数标识了要接收匹配项的回调函数(objects corresponding to the tabs open in a browser window. Its first argument defines a set of criteria for selecting the tabs and the second identifies a callback function to receive matching) Tab
对象.的(objects. The) queryInfo
对象提供了许多用于选择选项卡的属性,并且所有属性都是可选的:(object provides many properties for selecting tabs and all are optional:)
index
—标签在窗口中的位置(— the position of the tab in the window)title
—标签的标题(— the tab’s title)url
—标签的网址格式(— the tab’s URL pattern)active
/(/)highlighted
/(/)pinned
/(/)audible
/(/)muted
—布尔属性,表示选项卡的状态(— boolean properties representing the tab’s state)currentWindow
/(/)lastFocusedWindow
—选项卡是在当前窗口还是上一个窗口中(— whether the tab is in the current or previous window) 例如,以下代码中的回调函数接收一个包含一个对象的数组:(For example, the callback function in the following code receives an array containing one object: the)Tab
对应于当前窗口中的活动选项卡:(corresponding to the active tab in the current window:)
chrome.tabs.query({currentWindow: true, active: true}, function (tabs) { ... });
一种(A) Tab
对象包含许多属性,这些属性提供有关基础浏览器选项卡的信息.表6列出了其中的十二个,可以找到完整列表(object contains many properties that provide information about the underlying browser tab. Table 6 lists twelve of them and the full list can be found) 这里(here) .(.)
表6:Tab对象的属性(节略)(Table 6: Properties of the Tab Object (Abridged))
属性(Property) | 数据类型(Data Type) | 描述(Description) |
---|---|---|
id |
Integer |
标签的唯一标识符(Unique identifier for the tab) |
index |
Integer |
标签在窗口中的位置(从0开始)(The position of the tab in the window (starts at 0)) |
title |
String |
标签的标题(The tab’s title) |
url |
String |
标签中显示的URL(The URL displayed in the tab) |
windowId |
Integer |
选项卡窗口的唯一标识符(Unique identifier for the tab’s window) |
active/pinned/ |
||
highlighted/audible |
Boolean |
浏览器标签的特征(Characteristics of the browser tab) |
width/height |
Integer |
标签的尺寸(The tab’s dimensions) |
openerTabId |
Integer |
打开此标签的标签的ID(The ID of the tab that opened this tab) |
这些字段是只读的.要更改标签的属性,脚本需要调用(These fields are read-only. To change a tab’s properties, a script needs to call the) update
表5中的函数.第二个参数是一个对象,其属性包含选项卡属性的名称和所需值.可以更改的属性是(function from Table 5. The second argument is an object whose properties contain the names and desired values for the tab’s properties. The properties that can be changed are) url
,(,) active
,(,) highlighted
,(,) pinned
,(,) muted
和(, and) openerTabId
.它们具有与表6中列出的属性相同的类型.(. These have the same types as the properties listed in Table 6.)
例如,以下代码在当前窗口中找到活动标签并打开Google主页:(For example, the following code finds the active tab in the current window and opens the Google homepage:)
chrome.tabs.query({currentWindow: true, active: true}, function (tabs) {
chrome.tabs.update(tabs[0].id, {url: "http://www.google.com"});
});
要修改标签页的URL,标题或网站图标,扩展名必须请求权限才能修改浏览器的标签页.这是通过添加一个(To modify a tab’s URL, title, or favicon, an extension must request permission to modify the browser’s tabs. This is accomplished by adding a) "tabs"
清单清单的字符串(string to the manifest’s) permissions
领域.本节末尾讨论的示例代码演示了它是如何工作的.(field. The example code discussed at the end of this section demonstrates how this works.)
的(The) create
表5中的function在当前浏览器窗口中添加了一个新标签.第二个参数的属性初始化选项卡的特征:(function in Table 5 adds a new tab to the current browser window. The properties of the second argument initialize the tab’s characteristics:) url
,(,) active
,(,) index
,(,) pinned
,(,) windowId
和(, and) openerTabId
.索引值确定选项卡的位置,并将其限制在零和窗口中的选项卡数量之间.(. The index value determines the tab’s position, and will be clamped between zero and the number of tabs in the window.)
的(The) remove
功能会根据其ID关闭一个或多个标签.例如,以下代码查找并关闭在Chrome开发者文档中打开到页面的每个选项卡:(function closes one or more tabs according to their IDs. For example, the following code finds and closes every tab open to a page in the Chrome developer documentation:)
chrome.tabs.query({url: "https://developer.chrome.com/*"}, function(tabs) {
for(tab = 0; tab < tabs.length; tab++) {
chrome.tabs.remove(tabs[tab].id);
}
});
表5中的最后一个功能(The last function in Table 5,) executeScript
,将JavaScript代码或CSS样式注入标签中.第二个参数标识代码/CSS及其注入方式.该对象具有六个属性,所有属性都是可选的:(, injects JavaScript code or CSS styling into a tab. The second argument identifies the code/CSS and the manner in which it should be injected. This object has six properties and all of them are optional:)
code
—将JavaScript代码或CSS规则插入标签中(— The JavaScript code or CSS rules to be injected into the tab)file
—包含要注入的JavaScript代码或CSS规则的文件(— The file containing the JavaScript code or CSS rules to be injected)allFrames
—如果为true,则JavaScript/CSS将注入到选项卡的每个框架中,而不仅仅是顶部框架(— If true, the JavaScript/CSS will be injected into every frame of the tab instead of just the top frame)frameId
—应在其中插入JavaScript/CSS的框架的ID(默认值:0,顶部框架)(— The ID of the frame where the JavaScript/CSS should be injected (default: 0, the top frame))matchAboutBlank
—如果为true,则JavaScript/CSS将注入到about:blank和about:srcdoc框架中(— If true, the JavaScript/CSS will be injected into about:blank and about:srcdoc frames)runAt
—应尽快注入JavaScript/CSS((— The soonest the JavaScript/CSS should be injected ()document_start
,(,)document_idle
, 要么(, or)document_end
)()) 这是一项强大的功能,因为它允许后台脚本在特定选项卡中动态执行内容脚本.例如,以下代码在索引为1的标签中的tab.js中执行JavaScript:(This is a powerful function because it allows a background script to dynamically execute a content script in a specific tab. For example, the following code executes the JavaScript in tab.js in the tab whose index is 1:)
chrome.tabs.query({index: 1}, function (tabs) {
chrome.tabs.executeScript(tabs[0].id, {file: "tab.js"});
});
要成功注入代码或CSS,清单必须请求访问选项卡URL的权限.这可以通过在清单的(To successfully inject code or CSS, the manifest must request permission to access the tab’s URL. This can be accomplished by adding a URL pattern to the manifest’s) permissions
领域.例如,以下清单代码请求访问Chrome浏览器标签和Google页面的权限:(field. For example, the following manifest code requests permission to access Chrome’s tabs and Google’s pages:)
"permissions": ["tabs", "https://www.google.com/*"]
3.2.3在脚本之间传递消息(3.2.3 Passing Messages Between Scripts)
如前所述,后台脚本可以访问整个Chrome API,但不能访问网页的内容.内容脚本可以访问网页的内容,但只能访问Chrome API的一部分.为了使扩展能够充分利用两种类型的脚本,它需要一种在它们之间传输数据的方法.这就是所谓的(As discussed earlier, a background script can access the entire Chrome API but not the content of a web page. A content script can access the content of a web page but only a limited part of the Chrome API. For an extension to take full advantage of both types of scripts, it needs a way to transfer data between them. This is called)信息传递(message passing).消息传递可用于在不同扩展之间以及扩展与应用之间进行通信.但是本节重点介绍在同一扩展中的脚本之间传递消息.(. Message passing can be used to communicate between different extensions and between extensions and apps. But this section focuses on passing messages between scripts in the same extension.)
的(The) chrome.runtime
API提供了两种在扩展中的脚本之间传递消息的机制.第一种涉及一次传输一个消息.第二个创建用于发送和接收消息的长期连接.(API provides two mechanisms for passing messages between scripts in an extension. The first involves transferring messages one at a time. The second creates a long-term connection for sending and receiving messages.)
表7列出了(Table 7 lists the functions of) chrome.runtime
使消息传递成为可能.可以在后台脚本和内容脚本中调用它们,并且经常使用它们在两种类型的脚本之间传输数据.(that make message passing possible. They can be invoked in background scripts and content scripts, and they’re frequently employed to transfer data between both types of scripts.)
表7:脚本间通信的功能(Table 7: Functions for Inter-Script Communication)
功能(Function) | 信息(Information) |
---|---|
sendMessage(String id, |
|
any message, |
|
Object options, |
|
Function callback) |
使用给定的ID向扩展发送消息(Sends a message to the extension with the given ID) |
onMessage.addListener |
|
(Function callback) |
分配功能以接收传入消息(Assigns a function to receive an incoming message) |
connect(String id, |
|
Object connectInfo) |
创建具有给定ID的扩展的持久连接(Creates a persistent connection to the extension with the given ID) |
onConnect.addListener |
|
(Function callback) |
分配功能以通过连接接收数据(Assigns a function to receive data through the connection) |
的(The) sendMessage
函数将消息发送到扩展程序的后台脚本.它有四个参数:(function sends a message to an extension’s background scripts. It has four arguments:)
id
—接收消息的扩展名的ID.如果发件人和收件人属于同一个分机,则可以省略.(— the ID of the extension to receive the message. This can be omitted if the sender and recipient belong to the same extension.)message
—要发送的消息.这可以采用任何类型,通常是常规的JSON对象.(— the message to be sent. This can take any type, and is usually a regular JSON object.)options
—可选的配置对象.仅在扩展之外发送数据时才需要(— optional configuration object. This only needed when sending data outside of the extension)callback
—接收收件人回复的可选功能(如果有)(— optional function that receives the recipient’s response (if available)) 例如,以下代码将简单对象发送到其扩展名内的脚本.回调函数记录(For example, the following code sends a simple object to a script within its extension. The callback function logs the)data
收件人回复的字段:(field of the recipient’s response:)
chrome.runtime.sendMessage({data: "Hi there!"}, function(response) {
console.log(response.msg);
});
另一个脚本可以通过(Another script can listen for incoming messages with) onMessage.addListener
.此函数需要一个接收三个参数的回调函数:(. This function requires a callback function that receives three arguments:)
message
—传入消息(— the incoming message)sender
- 一种(— a)MessageSender
标识发送者的对象.这具有五个可选字段:(object that identifies the sender. This has five optional fields:)id
,(,)frameId
,(,)tab
,(,)url
和(, and)tlsChannelId
sendResponse
—可以调用以向发送方提供响应的函数(— a function that can be called to provide the sender with a response) 以下代码演示了如何(The following code demonstrates how)onMessage.addListener
可以使用.每当收到消息时,脚本都会打印消息的(can be used. Whenever a message is received, the script prints the message’s)data
字段和发件人标签的ID.响应包含一个简单的对象.(field and the ID of the sender’s tab. The response consists of a simple object.)
chrome.runtime.onMessage.addListener(
function(message, sender, sendResponse) {
console.log("Message: " + message.data);
console.log("Sender's tab ID: " + sender.tab.id);
sendResponse({msg: "Hi yourself!"});
}
);
前面的代码可以将消息发送到后台脚本,但是如果收件人是内容脚本,则会出现问题:执行内容脚本的选项卡需要标识.在这种情况下,发件人需要打电话(The preceding code can send a message to a background script, but there’s a problem if the recipient is a content script: the tab executing the content script needs to be identified. In this case, the sender needs to call) chrome.tabs.sendMessage
代替(instead of) chrome.runtime.sendMessage
.这两个函数几乎相同,但是第一个参数(. The two functions are almost identical, but the first argument of) chrome.tabs.sendMessage
是用于接收消息的选项卡的ID.(is the ID of the tab to receive the message.)
如果双方需要相互发送多条消息,则建立长期连接是有效的.要连接到后台脚本,(If the two parties need to send multiple messages to one another, it’s efficient to set up a long-lived connection. To connect to a background script, the) chrome.runtime.connect
函数接受两个参数:(function accepts two arguments:)
id
—接收消息的扩展名的ID.如果发件人和收件人属于同一个分机,则可以省略.(— the ID of the extension to receive the message. This can be omitted if the sender and recipient belong to the same extension.)connectInfo
—可选的配置对象.它可能包含两个属性:连接的名称((— an optional configuration object. This may contain two properties: a name for the connection ()name
)和一个布尔值,用于标识是否应发送TLS通道(() and a boolean that identifies whether the TLS channel should be sent ()includeTlsChannelId
).仅在扩展之外进行通信时才需要第二个属性.(). The second property is only needed when communicating outside of the extension.) 要连接到内容脚本,(To connect to a content script, the)chrome.tabs.connect
函数接受三个参数.第一个是收件人标签的ID,第二个和第三个参数与(function accepts three arguments. The first is the ID of the recipient’s tab and the second and third arguments are identical to the)id
和(and)connectInfo
的论点(arguments of)chrome.runtime.connect
.都(. Both)connect
函数返回一个(functions return a)Port
,代表两方之间的长期连接.以下代码显示了(, which represents a long-lived connection between two parties. The following code shows how)chrome.tabs.connect
可以使用:(can be used:)
chrome.tabs.query({currentWindow: true, active: true}, function (tabs) {
chrome.tabs.connect(tabs[0].id);
});
后台脚本和内容脚本可以侦听与(Background scripts and content scripts can listen for connections with) onConnect.addListener
.这需要一个回调函数来接收(. This requires a callback function that receives the) Port
代表新的连接.一种(that represents the new connection. A) Port
对象具有七个属性,表8列出了每个属性.(object has seven properties and Table 8 lists each of them.)
表8:端口对象的属性(Table 8: Properties of the Port Object)
属性(Property) | 数据类型(Data Type) | 描述(Description) |
---|---|---|
name |
String |
端口名称(由(Name of the port (set by the) connect function) |
postMessage |
Function |
向对方发送消息(Sends a message to the other party) |
onMessage |
Object |
添加传入消息的侦听器(Adds a listener for incoming messages) |
disconnect |
Function |
终止连接(Terminates the connection) |
onDisconnect |
Object |
添加用于断开连接的侦听器(Adds a listener for disconnection) |
disconnect |
Function |
终止连接(Terminates the connection) |
sender |
MessageSender |
发起连接的一方(可选)(The party that initiated the connection (optional)) |
如(Like the) sendMessage
前面讨论的功能(function discussed earlier,) postMessage
以JSON对象的形式传输数据.区别在于(transfers data in the form of a JSON object. The difference is that) postMessage
仅具有一个参数:消息对象.这在下面的代码中显示,该代码在建立连接后立即发布一条消息:(has only one argument: the message object. This is shown in the following code, which posts a message as soon as a connection is established:)
chrome.runtime.onConnect.addListener(function(port) {
port.postMessage({"name": "value"});
});
的(The) Port
的(’s) onMessage
对象的工作方式与(object works the same way as) chrome.runtime.onMessage
.它提供了(. It provides an) addListener
定义在收到消息时要调用的回调函数的方法.回调没有理由访问响应函数,因为(method that defines a callback function to be invoked when a message is received. The callback has no reason to access a response function because) Port
沟通使响应变得不必要.以下代码显示了(communication makes the response unnecessary. The following code shows how the) Port
的(’s) onMessage
可以使用的对象:(object can be used:)
port.onMessage.addListener(function(message) {
console.log("Message: " + message.name);
});
任何一方都可以打电话(Either party can call) disconnect()
终止连接.除此之外(to terminate the connection. In addition, the) onDisconnect
对象提供了(object provides an) addListener
当脚本不再连接到脚本时响应的函数(function that responds when the script is no longer connected to a) Port
.(.)
3.3示例应用(3.3 Example Application)
本文的示例档案包含一个名为script_demo的文件夹.它包含一个扩展,用于演示内容脚本如何与后台脚本进行通信.更具体地说,它演示了事件处理,存储访问和消息传递.(This article’s example archive contains a folder called script_demo. This contains an extension that demonstrates how a content script can communicate with a background script. More specifically, it demonstrates event handling, storage access, and message passing.) script_demo/scripts文件夹包含两个脚本:content.js和background.js. content.js中的代码作为内容脚本运行,并给出为:(The script_demo/scripts folder contains two scripts: content.js and background.js. The code in content.js runs as a content script, and is given as:)
// Connect to background script
var port = chrome.runtime.connect();
// Listen for response
port.onMessage.addListener(function(message, sender) {
// Print and store message data
console.log("Received color: " + message.color);
chrome.storage.local.set(message, function() {
port.postMessage({"status": "Communication successful!"});
});
});
该脚本首先创建与后台脚本的连接.然后,它等待消息,将消息打印到控制台,然后使用(This script starts by creating a connection to the background script. Then it waits for a message, prints a message to the console, and uses the) chrome.storage
用于存储消息数据的API.存储消息后,它将消息发送到后台脚本.后台脚本的代码为:(API to store the message’s data. After storing the message, it sends a message to the background script. The code for the background script is given as:)
// Wait for connection from content script
chrome.runtime.onConnect.addListener(function(port) {
// Send data through port
port.postMessage({"color": "green"});
// Wait for incoming message
port.onMessage.addListener(function(message) {
// Retrieve data from storage
chrome.storage.local.get("color", function(obj) {
if (obj.color === "green") {
console.log("Status: " + message.status);
}
});
});
});
后台脚本等待传入的连接,将消息发布到内容脚本,然后等待消息到达.接收到消息后,后台脚本将访问本地存储,检查返回的值,然后将消息打印到控制台.(The background script waits for an incoming connection, posts a message to the content script, and then waits for a message to arrive. When it receives the message, the background script accesses local storage, checks the returned value, and prints a message to the console.) 在离开主题之前,我想谈谈关于扩展脚本的三点:(Before leaving the subject, there are three points I’d like to mention regarding the scripts an extension:)
- 与其将消息从后台脚本发送到内容脚本,不如让后台脚本使用以下命令执行脚本更为方便(Instead of sending messages from a background script to a content script, it can be more convenient for the background script to execute a script using)
chrome.tabs.executeScript
.后台脚本可以访问处理结果(. The background script can access the processing result in)executeScript
的回调函数.(’s callback function.) - 确保清单的权限设置正确.如果脚本需要访问存储,(Make sure the manifest’s permissions are set correctly. If a script needs to access storage,)
"storage"
应该在权限数组中.如果脚本需要修改标签页的网址,标题或网站图标,(should be in the permissions array. If a script needs to modify a tab’s URL, title, or favicon,)"tabs"
应该在数组中.(should be in the array.) - “(The “)
o
在(” in)onMessage
和(and)onConnect
总是小写.我不小心用大写字母键入了它,花了一个多小时才弄清楚扩展名为什么不起作用.(is always lowercase. I accidentally typed it in uppercase and it took me over an hour to figure out why the extension wasn’t working.)
4.行动(4. Actions)
在Chrome扩展程序中,操作由工具栏中的图标表示,单击该图标可触发扩展程序的反应.每个扩展程序最多只能有一个操作,这可以是浏览器操作或页面操作.无论浏览器中打开的页面如何,浏览器动作均保持活动状态.页面操作仅对特定页面有效.(In a Chrome extension, an action is represented by an icon in the toolbar that triggers a reaction from the extension when clicked. Every extension can have at most one action, and this can be a browser action or a page action. A browser action remains active regardless of the page open in the browser. A page action is only active for specific pages.)
4.1浏览器动作(4.1 Browser Actions)
扩展程序的浏览器操作可以通过添加一个(An extension’s browser action can be defined by adding a) browser_action
manifest.json的属性.它可以包含定义操作各方面的三个属性(所有属性都是可选的):(property to manifest.json. This can contain three properties that define aspects of the action (all are optional):)
default_icon
—动作的图标可以是HTML5画布或静态图像.静态图片的尺寸必须为19x19或38x38像素,支持的格式包括BMP,GIF,ICO,JPEG或PNG.对于解压缩的扩展名,仅支持PNG格式.(— The action’s icon can be an HTML5 canvas or a static image. Static images must be 19x19 or 38x38 pixels in size, and supported formats include BMP, GIF, ICO, JPEG, or PNG. For unpacked extensions, only the PNG format is supported.)default_title
—指定当用户的鼠标悬停在图标上时要显示的工具提示.(— Assigns a tooltip to be displayed when the user’s mouse hovers over the icon.)default_popup
—标识显示弹出菜单的HTML文件.(— Identifies an HTML file that displays a popup menu.) 弹出窗口是用户单击操作时出现的页面.该页面的外观是使用与(A popup is a page that appears when the user clicks the action. The page’s appearance is set using the HTML page associated with the)default_popup
属性.例如,以下HTML在弹出窗口中定义了三个复选框:(property. For example, the following HTML defines three checkboxes in the popup:)
<!DOCTYPE html>
<html>
<body style="width: 80px">
<input type="checkbox" id="opt1">Option 1<br>
<input type="checkbox" id="opt2">Option 2<br>
<input type="checkbox" id="opt3">Option 3<br>
</body>
</html>
图3显示了结果弹出窗口的外观.(Figure 3 shows what the resulting popup looks like.)
图3:带有弹出窗口的浏览器操作(Figure 3: Browser Action with a Popup)
如果浏览器操作没有弹出窗口,则单击该操作时后台脚本可以响应.通过调用使之成为可能(If a browser action doesn’t have a popup, a background script can respond when the action is clicked. This is made possible by calling) chrome.browserAction.onClicked.addListener
.这接受一个回调函数,该函数返回(. This accepts a callback function that returns the) Tab
单击操作时代表活动选项卡的对象.例如,每当单击浏览器操作时,以下代码都会显示当前选项卡的URL:(object representing the active tab when the action was clicked. For example, the following code prints the URL of the current tab whenever the browser action is clicked:)
chrome.browserAction.onClicked.addListener(function(tab) {
console.log("The tab's URL is " + tab.url);
});
的(The) chrome.browserAction
API提供的不仅仅是事件处理功能.它的功能可以获取有关动作的信息并动态配置其外观.表9列出了API的功能,并提供了每个功能的说明.(API provides more capabilities than just event handling. Its functions make it possible to obtain information about the action and dynamically configure its appearance. Table 9 lists the API’s functions and provides a description of each.)
表9:chrome.browserAction API的功能(Table 9: Functions of the chrome.browserAction API)
功能(Function) | 描述(Description) |
---|---|
enable(Integer tabId) |
启用给定标签的浏览器操作(Enable the browser action for the given tab) |
disable(Integer tabId) |
禁用给定标签的浏览器操作(Disable the browser action for the given tab) |
getTitle(Object props, |
|
Function callback) |
通过回调函数获取动作的标题(Obtains the action’s title through the callback function) |
setTitle(Object props) |
设置动作的标题(Sets the action’s title) |
setIcon(Object props) |
设置动作的图标(Sets the action’s icon) |
getBadgeText(Object props, |
|
Function callback) |
通过回调函数获取动作的徽章文本(Obtains the action’s badge text through the callback function) |
setBadgeText(Object props) |
设置动作的徽章文字(Sets the action’s badge text) |
getBadgeBackgroundColor |
|
(Object props, |
|
Function callback) |
获取动作徽章的背景色(Obtains the background color of the action’s badge) |
通过回调函数(through the callback function) | |
setBadgeBackgroundColor |
|
(Object props) |
设置动作徽章的背景颜色(Sets the background color of the action’s badge) |
getPopup(Object props, |
|
Function callback) |
通过获取操作的弹出文档(Obtains the action’s popup document through the) |
回调函数(callback function) | |
setPopup(Object props) |
设置操作的弹出文档(Sets the action’s popup document) |
通常,浏览器操作对于浏览器中的每个选项卡都具有相同的外观和行为.但是,使用这些功能可以指定应访问的选项卡.前两个功能根据选项卡的ID启用或禁用浏览器操作.禁用的操作在工具栏中显示为灰色.(In general, a browser action has the same appearance and behavior for every tab in the browser. But these functions make it possible to specify which tab should be accessed. The first two functions enable or disable a browser action according to the tab’s ID. A disabled action appears grayed in the toolbar.)
大部分的(Most of the) get**XYZ**
和(and) set**XYZ**
功能以相同的方式工作. getter函数接受一个可选对象,该对象标识该函数应用于哪个选项卡.第二个参数是接收所需信息的回调函数.例如,以下代码显示了(functions work in the same way. The getter functions accept an optional object that identifies which tab the function applies to. The second argument is a callback function that receives the desired information. For example, the following code shows how) getTitle
可以调用以获得活动选项卡的动作标题:(can be called to obtain the action’s title for the active tab:)
chrome.tabs.query({currentWindow: true, active: true}, function (tabs) {
chrome.browserAction.getTitle({tabId: tabs[0].id}, function (title) {
console.log("Title: " + title);
});
});
设置器功能如(Setter functions like) setTitle
接受类似的配置对象,但是第一个属性提供新的配置数据.例如,以下代码为索引为零的选项卡设置浏览器操作的标题.(accept a similar configuration object, but the first property provides the new configuration data. For example, the following code sets the browser action’s title for the tab whose index is zero.)
chrome.tabs.query({index: 0}, function (tabs) {
chrome.browserAction.setTitle({title: "New title", tabId: tabs[0].id});
});
浏览器操作可以在其图标旁边打印文本.这称为徽章,可以使用(A browser action can have text printed next to its icon. This is called a badge, and can be configured with the) setBadgeText
功能.例如,以下代码打印(function. For example, the following code prints) HI
在操作图标上方:(on top of the action’s icon:)
chrome.browserAction.setBadgeText({text: "HI"});
图4显示了带有徽章的动作:(Figure 4 shows what the action looks like with the badge:)
图4:带有徽章的浏览器操作(Figure 4: Browser Action with a Badge)
默认情况下,动作的徽章显示在红色矩形的内部.矩形的颜色可以用(By default, an action’s badge is displayed inside of a red rectangle. The rectangle’s color can be changed with) setBadgeBackgroundColor
.这接受一个配置对象,其(. This accepts a configuration object whose) color
属性可以以CSS颜色字符串或RGBA顺序的0到255之间的四个整数数组形式给出.例如,绿色可以指定为(property can be given as a CSS color string or as an array of four integers between 0 and 255 in RGBA order. For example, the color green can be given as) "#0f0"
,(,) "#00ff00"
, 要么(, or) [0, 255, 0, 255]
.以下代码显示了如何使用它:(. The following code shows how this can be used:)
chrome.browserAction.setBadgeBackgroundColor({color: "#0F0"});
如果浏览器操作有弹出窗口,(If a browser action has a popup,) getPopup
提供弹出窗口的URL.可选配置对象接受选项卡ID,并且回调函数将URL作为字符串接收.以下代码显示了如何使用它:(provides the popup’s URL. The optional configuration object accepts a tab ID and the callback function receives the URL as a string. The following code shows how this can be used:)
chrome.browserAction.getPopup({}, function(url) {
console.log("The popup's URL is " + url);
});
chrome.browserAction
不提供任何与弹出窗口通信或获取其状态的功能.但这可以使用前面讨论的消息传递机制来完成.在本节的最后将讨论与弹出窗口进行通信.(doesn’t provide any functions for communicating with a popup or obtaining its state. But this can be accomplished using the message passing mechanisms discussed earlier. Communicating with a popup will be discussed at the end of this section.)
4.2页面动作(4.2 Page Actions)
页面操作几乎与浏览器操作相同,并且可以具有图标,标题和弹出窗口.在manifest.json中,唯一的区别是(Page actions nearly identical to browser actions, and can have icons, titles, and popups. In manifest.json, the only difference is that the) browser_action
字段被替换为(field is replaced by) page_action
.可以显示如下:(. This can be shown as follows:)
"page_action": {
"default_icon": {
"19": "images/icon_19.png",
"38": "images/icon_38.png"
},
"default_title": "Page action",
"default_popup": "popup.html"
}
两种类型的操作之间的主要区别在于,默认情况下禁用页面操作(显示为灰色).要启用页面操作,需要调用后台脚本(The primary difference between the two types of actions is that page actions are disabled (grayed out) by default. To enable a page action, a background script needs to call) chrome.pageAction.show
带有标签ID.这意味着一次只能为一个选项卡启用页面操作.同样,(with a tab ID. This means a page action can only be enabled for one tab at a time. Similarly,) chrome.pageAction.hide
禁用指定选项卡的页面操作.(disables the page action for the specified tab.)
一个示例将阐明其工作原理.假定仅在选项卡的URL包含字符串的情况下才应启用页面操作(An example will clarify how this works. Suppose a page action should only be enabled if a tab’s URL contains the string) google
.后台脚本可以通过(. A background script can respond to tab changes through the) chrome.tabs.onUpdate
事件,并且当选项卡更改时,脚本可以检查URL.如下代码所示:(event, and when a tab changes, the script can check the URL. This is shown in the following code:)
// Assign a callback to respond to tab changes
chrome.tabs.onUpdated.addListener(testUrl);
function testUrl(id, info, tab) {
if (tab.url.indexOf("google") !== -1) {
chrome.pageAction.show(id);
}
};
请注意,为了使此代码正常工作,(Note that, for this code to work properly, the) "tabs"
字符串必须放在清单的(string must be placed in the manifest’s) permissions
数组.(array.)
除了(Besides) show
和(and) hide
,其中的功能(, the functions in) chrome.pageAction
基本上类似于(are essentially similar to those of) chrome.browserAction
.有两个重要区别:(. There are two important differences:)
- 选项卡ID属性永远不是可选的.页面操作始终为单个选项卡配置.(The tab ID property is never optional. Page actions are always configured for individual tabs.)
- 页面操作不支持徽章,因此没有类似的功能(Page actions don’t support badges, so there are no functions like)
setBadgeText
要么(or)getBadgeBackgroundColor
.(.) 页面动作中的弹出窗口的工作方式与浏览器动作中的弹出窗口相同.以下讨论说明了两种弹出窗口如何与后台脚本进行通信.(Popups in a page action work like those in a browser action. The following discussion explains how both kinds of popups can communicate with a background script.)
4.3弹出通讯(4.3 Popup Communication)
弹出页面配置有HTML,这意味着它们可以使用以下方式包含JavaScript代码(Popup pages are configured with HTML, which means they can include JavaScript code using) <script>
标签.方便地,弹出页面中的脚本可以访问后台脚本的所有功能.这意味着弹出脚本可以使用消息传递与其他脚本进行通信.(tags. Conveniently, scripts in a popup page can access all the capabilities of a background script. This means a popup script can communicate with other scripts using message passing.)
弹出式通讯在本文的示例档案中包含的action_demo扩展中进行了演示. popup.html页面上有三个复选框,其ID为(Popup communication is demonstrated in the action_demo extension contained in this article’s example archive. The popup.html page has three checkboxes whose IDs are) opt1
,(,) opt2
和(, and) opt3
.它执行popup.js中的代码,如下所示:(. It executes the code in popup.js, which is given as follows:)
// Create listeners for the three checkboxes
document.getElementById("opt1").addEventListener("change", opt1changed);
document.getElementById("opt2").addEventListener("change", opt2changed);
document.getElementById("opt3").addEventListener("change", opt3changed);
// Send a message when the first box changes
function opt1changed() {
var box1 = document.getElementById("opt1");
chrome.runtime.sendMessage({box: 1, checked: box1.checked});
}
// Send a message when the second box changes
function opt2changed() {
var box2 = document.getElementById("opt2");
chrome.runtime.sendMessage({box: 2, checked: box2.checked});
}
// Send a message when the third box changes
function opt3changed() {
var box3 = document.getElementById("opt3");
chrome.runtime.sendMessage({box: 3, checked: box3.checked});
}
选中或取消选中三个框中的任何一个时,popup.js都会调用(When any of the three boxes is checked or unchecked, popup.js calls) chrome.runtime.sendMessage
.这会将消息发送到后台脚本,以标识复选框的编号及其状态.后台脚本代码如下:(. This sends a message to the background script that identifies the number of the checkbox and its state. The background script code is given as follows:)
// Configure the browser action
chrome.runtime.onInstalled.addListener(function(obj) {
chrome.browserAction.setBadgeText({text: "YES"});
chrome.browserAction.setBadgeBackgroundColor({color: "#00F"});
});
// Wait for an incoming message
chrome.runtime.onMessage.addListener(
// Receive a message from the popup script
function(message, sender, sendResponse) {
console.log("Box" + message.box + " checked state: " + message.checked);
}
);
此后台脚本使用(This background script uses the) chrome.browserAction
设定动作徽章文字和背景颜色的API.然后它通过调用等待消息(API to set the action’s badge text and background color. Then it waits for a message by calling) chrome.runtime.onMessage.addListener
.收到消息后,脚本会将消息记录到控制台.(. When a message is received, the script logs a message to the console.)
此扩展程序演示了弹出窗口如何接收用户设置并将其发送到扩展程序的方法.但是有一个问题:弹出窗口的页面在每次关闭时都会重置.为了弥补这一点,可以持久存储弹出窗口的状态.(This extension demonstrates how an popup can receive user settings and send them to the extension. But there’s a problem: the popup’s page resets every time it’s closed. To make up for this, the popup’s state can be persistently stored accessing the) chrome.storage
前面讨论过的API.(API discussed earlier.)
历史(History)
2016/6/17-初次提交文章(6/17/2016 - Initial article submission)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
HTML Javascript Google chrome Dev 新闻 翻译