系列文章可以查看《浏览器扩展程序开发笔记》专栏
Options Pages
设置页面允许用户定制扩展程序,以更符合自己的使用习惯。
如果要为扩展程序添加设置页面,需要先在配置清单 manifest.json 的中进行声明注册,有两种类型的设置页面:
-
Full page options 整页的设置页面,需要打开一个标签页。
在配置清单的选项
options_page中声明注册作为设置页面的 HTML 文档的路径{ // ... "options_page": "options.html", }然后用户可以在浏览器工具栏的扩展程序图标右键点击选择「选项」打开设置页面
或者在扩展程序的「详情」页面中选择「扩展程序选项」打开设置页面
-
Embedded Options 内嵌的设置页面,以模态框的形式展示设置页面。
💡 模态框的大小会根据页面内容自动调整,但有时候可能并不奏效,此时可以为设置页面先提供一个最小的尺寸,以保证布局正常显示。
在配置清单的选项
options_ui.page中指向相应的 HTML 文档路径,并设置属性option_ui.open_in_tab为false,表示采用内嵌设置页(如果设置为true就会打开新的标签页来展示设置页面)。{ // ... "options_ui": { "page": "options.html", "open_in_tab": false }, }然后用户就可以在在浏览器工具栏的扩展程序图标右键点击选择「选项」,会跳转到相应扩展程序的详情页,同时打开模态框展示设置页面;或者在扩展程序的「详情」页面中选择「扩展程序选项」,打开模态框展示设置页面。
💡 在扩展程序的页面中可以通过方法
chrome.runtime.openOptionsPage()打开设置页面
<button id="go-to-options">Go to options</button>
document.querySelector('#go-to-options').addEventListener('click', function() {
// 先判断浏览器是否支持该方法
if (chrome.runtime.openOptionsPage) {
chrome.runtime.openOptionsPage();
} else {
// 如果不支持就手动基于页面路径打开设置页面
window.open(chrome.runtime.getURL('options.html'));
}
});
虽然两种方式都可以供用户设置参数,但是有一些不同:
-
对于内嵌型的设置页面,不支持部分 Tabs 相关的 API
- 无法使用 方法
chrome.tabs.query()通过设置页面的 URL 找到对应的 tab - 打开设置页面时,事件
chrome.tabs.onCreated.addListener()无法被监听到 - 当设置页面重载时,事件
chrome.tabs.onUpdated.addListener()无法被监听到
- 无法使用 方法
-
无法使用方法
chrome.tabs.connect()和方法chrome.tabs.sendMessage()发送信息,但方法chrome.runtime.connect()和方法chrome.runtime.sendMessage()并不受限制。💡 如果设置页面使用方法
chrome.runtime.connect()和方法chrome.runtime.sendMessage()传递信息,接收者并不能读取发送者 sender 的 tab 信息,只能读取到发送者的 url 信息(设置页面文档的路径)
💡 为了可以让用户的设置数据持久化及跨设备同步,可以使用 Chrome 提供的 storage.sync API,记得先在配置清单 manifest.json 中声明注册 strage 权限
Accessibility
可及性,又称为 a11y,是指一系列的设计指南,以便残障人士更易于使用扩展程序,例如快捷键命令可以让视觉障碍人士更方便地使用扩展程序,字幕和翻译功能对视觉障碍人士和外语者有帮助。
开发者可以遵循以下建议,以提高扩展程序的可及性 accessible:
-
使用正确的语义化 HTML 元素搭建 UI 控件,以便保障可及性。这些控件保证了可以通过键盘(Tab 键)访问操作,且它们的语义性让屏幕阅读器更容易理解。
-
如果需要使用非语义化的 HTML 元素或 JavaScript 构建 UI 控件时,可以通过 WAI-ARIA,Web Accessibility Initiative - Accessible Rich Internet Applications,一个由 W3C 制定的规范,它通过给 DOM 元素添加一些规定的属性,让我们的开发的网页应用更具语义化。
💡 WAI-ARIA 属性不会对 web 页面有任何影响,只是让浏览器暴露更多的信息给无障碍 API,例如屏幕阅读器。
该规范中三个主要的特性:
- 声明元素的角色和功能,例如
role="navigation"表示该元素的作用是导航 - 为元素定义额外的属性,例如
aria-require=true告知用户该表单是必添的 - 设定元素的状态,例如
aria-disable="true"表示该表单禁止输入
💡 状态和属性的差异之处就是:属性在应用的生命周期中不会改变,而状态可以,用编程的方法改变。
<div role="toolbar" tabindex="0" aria-activedescendant="button1"> <img src="buttoncut.png" role="button" alt="cut" id="button1"> <img src="buttoncopy.png" role="button" alt="copy" id="button2"> <img src="buttonpaste.png" role="button" alt="paste" id="button3"> </div>以上示例中,属性
tabindex="0"让该元素可以聚焦,并且可以通过键盘来导航,其聚焦顺序由 DOM 结构决定;属性aria-activedescendant指定该元素聚焦时,其子代哪一个元素先进行聚焦。 - 声明元素的角色和功能,例如
-
元素可聚焦让用户仅通过键盘也能操作扩展程序页面,应该保证按钮、菜单栏等元素可以聚焦。默认情况下,只有锚标签、按钮、表单控件可以通过键盘聚焦,但是我们可以通过为元素添加属性
tabIndex="0"让任意元素可以聚焦;也可以通过添加属性tabIndex="-1"让该元素无法通过键盘聚焦(但仍可以通过 JavaScript 编程聚焦elem.focus())。 -
与通过 Tab 键聚焦元素相比,快捷键可以让用户更方便地操作扩展程序页面的元素,可以参考官方示例如何用快捷键进行导航。如果在扩展程序的页面内提供了快捷键,应该在设置页面 options page 中告知用户。
-
以下设置可以完善内容的可访问性
-
文本:选择合适的字体和字号大小以确保文本内容的可读性,而且应该考虑视觉障碍者的使用体验,他们可能需要设置更大的字体,避免将自定义的快捷键与页面缩放的快捷键相冲突。为了确保版型的稳定,应该测试缩放至 200%,查看页面是否还显示正常。应该避免将文字嵌入到图片中,这样不仅无法调整字体,还无法让屏幕阅读器识别;如果必须将文字嵌入图片中,应该在图片的可替代文字(属性
alt)中包含这些文字内容,相关指南可以参考这里。 -
颜色:背景和内容的颜色应该有足够的对比度,可以使用 Colour Contrast Check 工具检查。对于颜色丰富的图表,可以使用色弱模拟器 Coblis 来查看它在不同程度的色弱症人士眼里的效果,调整图表的配色,以使扩展程序对于这些用户更友好。可以考虑为提供不同的色彩主题,或允许自定义配色方案,以便用户有更好的体验。
-
声音:如果扩展程序需要声音和视频传达信息,应该提供字幕和翻译功能,关于多媒体字幕的相关指南参考这里。
-
图片:为图片提供可替代文字,即属性
alt(文字内容应该用于阐明图像的目的,而不是描述图片的细节),而对于占位图和纯装饰作用的图片,应该将该属性值留空"",或使用 CSS 来实现(而不是用 DOM)<img src="img.jpg" alt="The logo for the extension">
-
-
更多相关资源:
Internationalization
参考:
-
关于 Internationalization 官方示例:
国际化 I18N 是指在开发扩展程序时,可以让用户按需切换语言。
💡 关于软件多语言版本的开发:
- 国际化 Internationalization,L18N:软件国际化是在软件设计和文档开发过程中,使得功能和代码设计能处理多种语言和文化传统,使创建不同语言版本时,不需要重新设计源程序代码的软件工程方法。
- 本地化 localization ,L10N:能够使网站、Web 应用或任何其他形式的内容适用于特定语言的范围和文化圈。
为了让扩展程序更方便地实现国际化,需要遵循以下建议:
-
将所有用户可见的内容(文本)放在一个
messages.json文档中,并将该文档放在_locales/_localeCode_相应的目录下(其中_localeCode_是一个语言编码,例如英语就应该使用en表示)。💡 如果项目中有
_locales目录,需要在配置清单manifest.json的选项default_locale中声明默认语言,可以在这里查看具体的语言代码。在
messages.json文档中,它以键值对的形式来定义内容,每一个键都包含一个需要国际化的项(大小写敏感),值是一个对象,其中常用的属性如下:- 属性
message是需要显示的内容 - (可选)属性
description是对该项的描述,便于告知翻译者该项的意义。
// messages.json { "search_string": { "message": "hello%20world", "description": "The string we search for. Put %20 between words that go together." }, // ... }💡 键名不能以
@@开头,这一类的键名是保留预定义的项,常用的预定义 message 项如下:Message 键名 解释 @@extension_id扩展程序的 ID,对于非国际化的扩展程序该 message 项也可用,💡 但不能用于 manifest.json中@@ui_locale当前使用的语言 @@bidi_dir当前的文字方向, ltr表示从左往右书写的文字,rtl表示从右往左书写的文字例如在 CSS 中使用扩展程序中的静态图片作为背景
body { background-image:url('chrome-extension://__MSG_@@extension_id__/background.png'); } - 属性
-
然后就可以在项目的其他文档中,通过 message 项来使用相应的数据:
- 在
manifest.json或 CSS 文档中,通过__MEG_messagename__来使用 message 相应的项messagename - 在扩展程序页面或 JavaScript 脚本中,通过方法
chrome.i18n.getMessage("messagename")获取相应的项messagename
💡 每次新增一种语言,就需要新增一个 message 文件到
_locales/_localeCode_目录里。每一种语言中,不必包含与默认语言中定义的全部 message 项。以上示例是支持英语、西班牙语、韩语的扩展程序项目文件结构
💡 浏览器会基于用户的语言设置和扩展程序的
default_locale设置来自动选择采用哪一个messages.json文档 - 在
Identity
扩展程序可以基于 OAuth 2.0 获取授权,访问 Chrome 用户信息,具体参考 chrome.identity API。
💡 关于该授权机制的介绍可以参考这里。
Management
管理已安装和正在运行的扩展程序,具体参考 chrome.management API。