NVDA 周知第二期——给你一个用官方版软件的理由
此时此刻:如果你遇到了在浏览器上无法使用回车键激活网页元素的问题,请检查自己是否正在使用三方优化版浏览器。
最近,社区里有一个提问:在使用 NVDA 屏幕阅读器和 Google Chrome 浏览器时遇到了一个奇怪的问题:无法用回车键或空格键点击网页上的链接。
这让我感到很意外,因为这种情况并不常见。恰逢周末,于是,我决定远程协助用户排查问题。
常规排查(无果)
我首先进行了常规的故障排除步骤:
- 检查 NVDA 设置: 确认回车/空格键的手势分配没有问题。
- 对比 Edge 浏览器: 看看在 Edge 中是否正常。
- 禁用插件: 尝试禁用 Chrome 和 NVDA 的所有插件。
- 检查版本: 确保 Chrome 和 NVDA 都是最新稳定版。
- NVDA 日志: 查看 NVDA 的调试日志,寻找错误信息。
然而,这些常规检查都没有发现任何异常。
“优化版” Chrome 浮出水面
在查看 Chrome 的版本信息时,我注意到一个细节:用户安装了一个名为 "Chrome++" 的第三方插件,而且使用的是国内 zd423 网站提供的“优化版” Chrome。同时,用户的 Edge 浏览器却一切正常。这让我对这个“优化版”产生了怀疑。
为了验证,我在自己的 Windows Sandbox 环境中安装了相同的 zd423 优化版 Chrome,问题果然重现了!
我首先尝试移除 Chrome++ 插件,问题立刻消失。用户说之前版本的优化版没问题,我又尝试恢复 Chrome++ 的默认设置(删除 chrome++.ini
),问题也消失了。
出于好奇,我打开了 chrome++.ini
配置文件,其中一行引起了我的注意:
command_line=--no-first-run --disable-logging --disable-breakpad --no-report-upload --disable-features=PrintCompositorLPAC --force-renderer-accessibility=basic
--force-renderer-accessibility=basic
?问题很可能就出在这里!我删除了这个参数,问题果然也解决了。
深入调查:--force-renderer-accessibility
是什么?
为了弄清这个参数的含义,我开始查阅 Chromium 的官方文档。Chromium 是 Chrome 浏览器的开源核心,Chrome 的很多功能都是基于 Chromium 实现的。
我在 Chromium 项目的文档库中找到了关于辅助功能(Accessibility)的概述:
在这篇文档的 "Command-Line Options" 部分,我找到了关于 --force-renderer-accessibility
参数的介绍:
原文:
--force-renderer-accessibility=[basic|form-controls|complete]
: Force accessibility to be enabled, with optional parameter to force the AXMode to one of the predefined bundles during the entire execution. If the optional parameter is invalid, then the default AXMode will be complete. If the optional parameter is missing, then the AXMode will initially default to complete but allow changes to the mode during execution.
文档解读:
这段话的意思是:
--force-renderer-accessibility
参数可以强制启用 Chrome 的辅助功能。- 它可以带一个可选参数(
basic
、form-controls
或complete
),用来指定辅助功能的级别。 - 如果提供了参数,则辅助功能级别会被 锁定,在 Chrome 运行期间不能更改。
- 如果不提供参数,则辅助功能级别初始为
complete
,但可以在运行时更改。 - 如果提供了无效参数, 则会回退到
complete
级别,且后续不能更改。
AXMode
:辅助功能的核心
文档中提到了一个关键概念:AXMode
。简单来说,AXMode
就像一个开关,控制着 Chrome 向屏幕阅读器等辅助技术提供多少关于网页的信息。
basic
、form-controls
和 complete
是 Chromium 预定义的三种 AXMode
:
basic
: 提供最基本的信息,例如元素的类型(按钮、链接等)。form-controls
: 在basic
的基础上,增加对表单控件(输入框、下拉菜单等)的支持。complete
: 提供最全面的信息,包括所有元素的详细属性和状态。
ax_mode.h
:代码层面的印证
为了进一步确认,我查看了 Chromium 的源代码。在 ui/accessibility/ax_mode.h
头文件中,我找到了 AXMode
的定义(部分):
namespace ui {
class AX_BASE_EXPORT AXMode {
public:
static constexpr uint32_t kNone = 0;
static constexpr uint32_t kNativeAPIs = 1 << 0;
static constexpr uint32_t kWebContents = 1 << 1;
// ... 其他标志 ...
// 预定义的组合
inline constexpr AXMode kAXModeBasic(AXMode::kNativeAPIs |
AXMode::kWebContents);
inline constexpr AXMode kAXModeComplete(AXMode::kNativeAPIs |
AXMode::kWebContents |
/* ... 其他标志 ... */);
// ...
};
}
这段代码证实了 AXMode
确实是一个控制辅助功能级别的机制,而 basic
、complete
等是预定义的组合。
真相大白
现在应该清楚了:
zd423 优化版 Chrome 使用了 --force-renderer-accessibility=basic
参数,强制将辅助功能级别锁定在了 basic
。 这导致 NVDA 无法获取足够的信息来“理解”网页上的某些元素,也就无法通过回车键或空格键来操作它们。
“负优化”
我在 chrome++.ini
中看到了下面的注释:
; new_tab_disable_name -- 当 new_tab_disable 为 1 时,在这里额外定义需要开启 new_tab_disable 的标签页名称
...
; -- 要使此开关生效,需要在 command_line 中添加 --force-renderer-accessibility=basic
zd423 优化版 Chrome 的初衷可能就在于此,但却错误地牺牲了辅助功能的兼容性。对于普通用户,或许没有如此深刻的感受,然而也并非完全没有副作用,实际上一些自动填充密码的扩展也依赖于辅助功能接口。对于完全依赖辅助功能的用户,比如屏幕阅读器用户,这会导致网页无法正常使用。当然,或许修改者本人也不知道这个开关意味着什么。
一些建议
这篇文章并不抨击三方优化版软件,尤其是国内某狗输入法,某即时聊天软件,以及某网盘,官方版实在是臃肿且流氓属性拉满。倘若你不得不用这些产品,一些值得信任的三方优化版用起来确实省心。
但诸如 Chrome、Firefox 这些浏览器,以及一些开原项目,我还是毫不犹豫的选择去官方渠道下载。
如果你也遇到了类似的问题,请检查是否使用了“优化版” Chrome 或类似软件,并尝试切换到官方版本。
官方版 Chrome 下载地址:
https://www.google.cn/chrome/
在 NVDA 中文站的导航页面我们整理了一个“常用软件”的可信任下载渠道。
你可以点击“阅读原文”访问该页面。