主导航中不能放入语言切换器,因其语义是页面间跳转,而语言切换是视图刷新,行为本质冲突;必须用独立包裹原生,并同步更新document.documentElement.lang、URL路径与localStorage。

主导航里不能塞语言切换按钮
主导航()的语义是“跳转到不同页面或锚点”,而语言切换是“刷新/重载当前页或切换视图”,二者行为本质冲突。把语言选择器(比如 )直接放进 会导致屏幕阅读器误报为“主导航的一部分”,键盘 Tab 焦点逻辑混乱,且 SEO 可能将语言选项当作独立入口页抓取。
常见错误现象:Uncaught TypeError: Cannot read property 'value' of null(JS 找不到 language-select),或切换后 document.documentElement.lang 没变、URL 路径没更新、屏幕阅读器仍用原语言朗读。
- 语言切换必须独立于主导航,推荐用
包裹
- 若 UI 上需视觉靠近主导航(如右对齐),可用 CSS 布局实现,但 DOM 结构必须分离
- 禁止在
内放 、 或表单控件
-
多语言站点中,主导航链接本身也需带
hreflang 属性,例如:@#@#@#@#@#@#@#@#@#@0
语言切换器必须用原生 ,且带标准 BCP 47 value
自定义下拉(如 +
)会破坏键盘导航、屏幕阅读器播报和移动端原生体验。原生
是唯一被所有辅助技术一致支持的语言选择控件。
关键实操点:
-
必须有 id(如 id="language-select"),否则 JS 获取不稳定
-
必须是标准 BCP 47 标签:en-US、zh-CN、ja——禁用 chinese、zh_CN、zh(后者在部分浏览器 fallback 为 und)
- 默认项应写成:
,避免空值触发误切换
- 切换时必须同步执行三件事:
document.documentElement.lang = 'zh-CN'、URL 路径替换(如 /about → /zh/about)、localStorage.setItem('preferred-lang', 'zh-CN')
主导航链接要配合 hreflang 和语言子目录结构
单纯靠 JS 切换语言文字,对 SEO 和无障碍是无效的。真正可落地的多语言导航,依赖服务端路径隔离 + 客户端语义补全。
比如用户在 /en/products 页面,主导航中的「关于我们」链接不应是 /about,而必须是:@#@#@#@#@#@#@#@#@#@1。同理,中文版对应链接是 @#@#@#@#@#@#@#@#@#@0。
- 每个语言版本应部署在独立子目录(
/、/en/、/zh/),而非同一 HTML 文件内靠 JS 切换
-
必须在 HTML 源码中真实存在,不能靠 JS 首屏后注入——否则 Safari 字体回退、Chrome 语音合成、NVDA 断句都会出错
- 主导航中所有链接的
href 必须与当前语言路径前缀一致,不可用相对路径(如 ../about.html)或无前缀路径(如 about.html)
- 构建时可通过模板引擎(如 Eleventy)自动注入语言前缀和
hreflang,纯静态页则需手动维护或脚本批量生成
多个 共存时,aria-label 必须用途明确
一个页面常有主导航、语言切换区、页脚链接组、移动端折叠菜单等,它们都用 ,但语义角色完全不同。全写 aria-label="导航" 等于没写。
正确做法是按功能命名,不模糊、不复用:
- 主导航:
(不是“主菜单”或“顶部导航”)
- 语言切换容器:
(注意:不是“语言导航”,因它不跳转页面)
- 页脚链接组:
(不是“页脚导航”,避免与可操作导航混淆)
- 移动端抽屉菜单:
,并配合 aria-hidden 控制隐藏状态
容易被忽略的是:这些 的 DOM 顺序、嵌套层级和是否包裹真实可跳转链接,直接影响读屏器播报顺序和焦点流。语言切换器哪怕视觉上在右上角,DOM 位置也建议放在 内主导航之后,符合用户心智模型。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!