跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

实现 URL 锚点自动展开 FAQ 项的完整解决方案

本文详解如何在页面加载时,根据 URL 中的 fragment(如 #faq-0)自动展开对应 FAQ 答案项,包括 DOM 定位、样式激活、无障碍属性同步及 Drupal 行为集成要点。 本文详解如何在页面加载时,根据 url 中的 fragment(如 `#faq-0`)自动展开对应 faq 答案项,包括 dom 定位、样式激活、无障碍属性同步及 drupal 行为集成要点。 在构建可访问、用户友好的 FAQ 页面时,支持通过 URL 锚点(fragment identifier)直接定位并展开指定问题的答案,是提升用户体验与 SEO 友好性的关键实践。例如,当用户访问 https://example.com/services/faq#faq-2 时,页面应自动显示 ID 为 faq-2 的答案内容,并同步更新其关联问题项的 aria-expanded 状态,确保符合 WCAG 2.1 标准。 ✅ 正确实现逻辑 仅调用 $(hash).show() 通常无效,原因有三: .show() 会覆盖内联 style,但可能忽略自定义过渡动画; 它不设置 data-slide-toggle="true" 等业务所需属性; 更重要的是——它 不会同步更新对应问题
  • 元素的 aria-expanded="true" 和 aria-controls 关系 ,导致屏幕阅读器无法正确播报展开状态。 因此,推荐采用 显式 CSS 控制 + 属性同步 + 无障碍语义补全 的组合方案:
    (function ($, Drupal) { 'use strict'; Drupal.behaviors.faqAutoExpand = { attach: function (context, settings) { // 在 DOM 就绪后执行(确保 FAQ 元素已渲染) $(document).ready(function () { const hash = window.location.hash; // 验证哈希值是否匹配 FAQ 答案 ID 模式(如 #faq-0, #faq-1...) if (hash && /^#faq-\d+$/.test(hash)) { const $answer = $(hash); if ($answer.length) { // 1. 强制设置 display: block 与过渡效果(复现 JS 动画行为) $answer.css({ 'display': 'block', 'transition': 'all 300ms ease-in' }).data('slide-toggle', true); // 2. 查找并更新对应的问题项:定位 aria-controls 值等于当前 hash 的
  • const controlId = hash.substring(1); // 移除 '#' → "faq-0" const $question = $('li[aria-controls="' + controlId + '"]'); if ($question.length) { // 同步 aria-expanded="true",并确保 tabindex 可聚焦(增强可访问性) $question .attr('aria-expanded', 'true') .attr('tabindex', '0'); // 可选:滚动到问题项顶部,提升可见性 $question[0].scrollIntoView({ behavior: 'smooth', block: 'nearest' }); } } } }); } }; })(jQuery, Drupal);
  • ⚠️ 注意事项与最佳实践 执行时机至关重要 :务必在 $(document).ready() 或 Drupal 的 attach 回调中执行,避免因 DOM 未加载完成导致元素查找失败; 哈希校验不可省略 :使用正则 /^#faq-\d+$/ 过滤非法哈希,防止 XSS 风险或 DOM 查询异常; 无障碍必须同步 :aria-expanded 是 ARIA 必需属性,仅展开内容而不更新该属性将导致屏幕阅读器误读; 避免依赖 :target 伪类 :虽然 CSS :target { display: block; } 简洁,但它无法触发 JavaScript 动画、设置 data-* 属性或更新 aria-*,且不兼容旧版 IE/部分移动浏览器; Drupal 集成提示 :若 FAQ 内容由 Views 或 Paragraphs 动态生成,请确保该行为绑定在最外层容器(如 .list--faq)的 context 下,以支持 AJAX 加载后的二次初始化。 ✅ 效果验证清单 检查项预期结果访问 #faq-1#faq-1 元素可见,且 display: block + transition 生效对应问题项aria-controls="faq-1" 的
  • 具有 aria-expanded="true"键盘导航展开后问题项可被 Tab 聚焦,按 Enter/Space 应可收起(需额外实现 toggle 逻辑)屏幕阅读器朗读“问题文本,已展开”(依赖正确 aria-expanded 和 role="button" 建议) 通过以上方案,你不仅实现了锚点驱动的 FAQ 展开功能,更保障了功能的鲁棒性、可访问性与框架兼容性,为用户提供一致、可靠、符合标准的交互体验。
  • 相关文章