npm.io
1.0.1 • Published yesterday

@william-xu-web/c-a11y

Licence
MIT
Version
1.0.1
Deps
0
Size
156 kB
Vulns
0
Weekly
0

网页无障碍辅助插件

A11y 是一个轻量、独立、可无缝集成到任何网页的无障碍工具栏。它通过浮动按钮提供 20 余项辅助功能,覆盖视觉、运动、认知与听觉障碍,帮助您快速提升网站的可访问性,并满足 WCAG 2.1 合规要求。

快速开始

方式一:NPM

yarn add @william-xu-web/c-a11y
import { init } from "@william-xu-web/c-a11y";

const widget = init({
  lang: "zh",
  position: "bottom-right",
});

// 需要时销毁插件并清理所有事件监听
widget.destroy();
方式二:Script 标签

在 HTML 中引入脚本,脚本从 node_modules 目录下的 c-a11y.min.js 文件引入,插件即自动初始化,无需额外 JavaScript 代码:

<script src="/path/to/c-a11y.min.js" defer></script>

功能全景

所有功能均按需启用,用户可随时开关,偏好设置自动保存至本地。

视觉与显示辅助
功能 WCAG 参考 适用人群
字体缩放(放大/缩小/重置) 1.4.4 低视力、老年人
高对比度模式(深色/浅色/反色) 1.4.3 低视力
深色模式 1.4.3 光敏感人群
灰度显示 1.4.1 色盲
色彩饱和度滑块 1.4.1 色彩敏感者
文字间距调整 1.4.12 阅读障碍、低视力
阅读障碍专用字体(OpenDyslexic) 最佳实践 阅读障碍
隐藏图片 最佳实践 认知障碍
色盲模拟滤镜 1.4.1 开发者测试、无障碍意识教育
导航与阅读辅助
功能 WCAG 参考 适用人群
全键盘导航支持 2.1.1 运动障碍
焦点指示器增强 2.4.7 运动障碍、低视力
标题地图 / 页面目录 2.4.10 屏幕阅读器用户
ARIA 地标结构展示 2.4.1 屏幕阅读器用户
阅读辅助标尺(遮光引导线) 最佳实践 阅读障碍、多动症
行聚焦 / 内容遮罩 最佳实践 多动症、认知障碍
大光标模式 最佳实践 运动障碍、低视力
屏幕阅读器预览 1.1.1, 1.3.1 开发者、测试人员
媒体与内容辅助
功能 WCAG 参考 适用人群
悬停朗读(TTS) 最佳实践 视障、低视力
选中朗读(TTS) 最佳实践 视障、低视力
整页朗读(TTS) 最佳实践 视障、低视力
链接高亮显示 1.4.1, 2.4.4 低视力、认知障碍
图片替代文本覆盖显示 1.1.1 视障、低视力
停止所有动画 2.3.1, 2.3.3 癫痫、前庭障碍
静音所有声音 1.4.2 听障、认知障碍

配置参数

您可以通过全局对象 window.OpenA11yConfig 在脚本加载前进行配置。

<script>
  window.OpenA11yConfig = {
    position: "bottom-right", // 按钮位置
    lang: "zh", // 界面语言
    bottomOffset: 20, // 桌面端向上偏移(px)
    mobileBottomOffset: 60, // 移动端向上偏移(px)
    statementUrl: "/accessibility-statement", // 外部无障碍声明链接
    statementData: {
      // 内置声明生成器数据
      orgName: "我的公司",
      orgPhone: "13088888888",
      orgEmail: "access@example.com",
      coordinatorName: "张三",
      lastAuditDate: "2026-01-15",
    },
  };
</script>
<script src="/path/to/c-a11y.min.js" defer></script>
配置项说明
参数 类型 默认值 说明
position string 'bottom-left' 可选:bottom-leftbottom-righttop-lefttop-right
lang string 自动检测 界面语言:'zh''en'
bottomOffset number 0 桌面端(屏幕 > 768px)按钮额外向上偏移,仅对底部位置生效
mobileBottomOffset number 0 移动端(屏幕 ≤ 768px)额外向上偏移,适用于底部固定导航栏的页面
statementUrl string 若您已有无障碍声明页面,可在此填写完整 URL
statementData object 若需内置声明生成器,提供机构信息即可自动生成声明

多语言支持

插件界面内置 中文(zh)英语(en) 两种语言,用户可随时在工具栏中切换。

合规性说明

本插件不仅覆盖 WCAG 2.1 的常用标准,还额外支持以下成功准则:

  • 1.4.10 回流(Reflow)
  • 1.4.12 文字间距(Text Spacing)
  • 1.4.13 悬停或焦点时的内容(Content on Hover or Focus)
  • 2.3.3 交互动画(Animation from Interactions)
  • 4.1.3 状态消息(Status Messages)

项目架构

目录结构
src/
  c-a11y.js            # 主入口
  styles.js            # 所有 CSS(注入 Shadow DOM)
  i18n.js              # 中/英翻译
  storage.js           # localStorage 持久化
  utils.js             # 共用工具函数
  modules/             # 每个功能独立模块(共 24 个)
dist/
  c-a11y.min.js        # 压缩版 IIFE(约 89 KB)
  c-a11y.esm.js        # ES Module 版本(供打包工具使用)
demo.html              # 功能演示页面
设计特点
  • Shadow DOM — 样式隔离,完全避免与宿主页面 CSS 冲突。
  • 零依赖 — 纯原生 JavaScript,无需加载任何第三方库。
  • 模块化 — 每个功能提供 enable() / disable() / toggle() 方法,便于扩展。
  • 状态持久化 — 用户偏好自动保存至 localStorage,跨会话保留。
  • ARIA 实时区域 — 为屏幕阅读器提供状态通知(WCAG 4.1.3)。

常见问题

悬停朗读/选中朗读无法正确朗读中文

问题描述

当页面 HTML 设置了 <html lang="en"> 时,即使插件界面切换到中文,悬停朗读和选中朗读功能仍会使用英文语音朗读中文内容,导致发音异常或无法理解。

原因分析

TTS(文本转语音)模块的语言检测逻辑优先使用页面 HTML 的 lang 属性:

_getLang() {
  const pageLang = document.documentElement.lang;  // 优先读取 <html lang="...">
  const raw = pageLang || getLanguage() || 'en';   // 其次才是插件界面语言
  return LANG_MAP[raw] || raw;
}

这样设计是为了让 TTS 遵循页面的内容语言,而非插件的界面语言。例如,一个英文网站(<html lang="en">)上使用中文界面的用户,朗读时仍应使用英文语音。

解决方案

  1. 推荐做法:在页面 HTML 中正确设置语言属性
<!-- 中文网站 -->
<html lang="zh">
  <!-- 或更精确 -->
  <html lang="zh-CN"></html>
</html>
  1. 临时方案:如果页面语言与内容语言不一致,可以在控制台临时修改:
document.documentElement.lang = "zh-CN";
  1. 检查系统语音:确保操作系统已安装中文语音包
// 在浏览器控制台运行,查看是否有中文语音
speechSynthesis.getVoices().filter((v) => v.lang.includes("zh"));
  • macOS:自带中文语音(Ting-Ting)
  • Windows:需在"设置 → 时间和语言 → 语言"中添加中文语言包
  • Linux:通常需要额外安装 espeak 或 festival 等语音合成引擎
Webpack3 引入 ES Module 依赖包编译报 Unexpected token 语法错误

问题描述

项目基于 Webpack3 构建,引入 @william-xu-web/c-a11y 依赖后启动编译报错,出现 Unexpected token 错误,根源为该依赖打包产物为 ES Module 格式(含 import/export 语法),Webpack3 编译时无法识别解析 ESM 语法,构建流程直接中断。

原因分析

  1. Webpack3 仅原生支持 CommonJS 模块化语法,不兼容 ES Module (import/export) 语法,无内置 ESM 解析能力。
  2. 目标依赖 @william-xu-web/c-a11y/dist/c-a11y.esm.js 采用 ESM 规范打包,存在 Webpack3 无法识别的模块化语法。
  3. Webpack3 无 type: "javascript/auto" 兼容配置,无法使用高版本 Webpack 适配 ESM 的配置写法。
  4. 项目默认 babel-loader 全局排除所有 node_modules 文件,未对该特殊依赖单独放行转译,导致 ESM 语法未被编译转换。

解决方案

1. 调整 babel-loader 排除规则(核心操作)

修改 Webpack3 构建配置,无需降级依赖包版本,适配性最强。

找到项目 webpack.base.conf.js 中的 babel-loader 配置,修改排除规则,放行报错依赖包参与 babel 转译:

// 原配置
{
  test: /\.js$/,
  loader: 'babel-loader',
  exclude: /node_modules/
}

// 修改后最终配置
{
  test: /\.js$/,
  loader: 'babel-loader',
  exclude: file => {
    // 仅放行 @william-xu-web-c-a11y 依赖,其余 node_modules 正常排除
    if (file.includes('@william-xu-web/c-a11y')) return false
    return /node_modules/.test(file)
  }
}

2. 配置 Babel 强制转换模块化规范

在项目根目录 .babelrc 中添加配置,强制将 ESM 转为 Webpack3 识别的 CommonJS:

{
  "presets": [
    [
      "env",
      {
        "modules": "commonjs"
      }
    ]
  ]
}

补充注意事项

  1. Webpack3 禁止使用 rule.type 相关配置,该配置仅 Webpack4 及以上版本支持。
  2. Vue-cli2 等基于 Webpack3 搭建的老旧 Vue 项目,统一修改 build/webpack.base.conf.js 配置即可。

浏览器支持

浏览器 最低版本
Chrome 80+
Firefox 78+
Safari 14+
Edge 80+

相关链接