
本文介绍如何在页面加载时,根据 URL 中的哈希(如 #faq-0)自动展开对应的 FAQ 答案项,并同步更新 ARIA 状态与过渡动画,确保可访问性与用户体验一致。
本文介绍如何在页面加载时,根据 url 中的哈希(如 `#faq-0`)自动展开对应的 faq 答案项,并同步更新 aria 状态与过渡动画,确保可访问性与用户体验一致。
在构建可访问、语义化的 FAQ 组件时,常采用「问题-答案」成对
但直接使用 $(hash).show() 通常无效,原因有三:
- show() 仅重置 display 为 block 或 inline,但无法还原原始 CSS 过渡效果(如 transition: all 300ms ease-in);
- 它不处理 ARIA 状态同步,导致屏幕阅读器仍播报“未展开”;
- 若答案项位于折叠容器内(如
- ),单纯显示
- 可能因父级样式限制而不可见。
✅ 正确做法是:精准注入内联样式 + 设置自定义数据属性 + 主动更新关联问题项的 ARIA 状态。
以下为推荐的完整实现(兼容 Drupal Behaviors 环境):
立即学习“Java免费学习笔记(深入)”;
(function ($, Drupal) { 'use strict'; Drupal.behaviors.faqHashExpand = { attach: function (context, settings) { // 延迟执行,确保 DOM 已就绪且 Drupal JS 初始化完成 setTimeout(function () { const hash = window.location.hash; if (!hash || !hash.startsWith('#faq-')) return; const $targetAnswer = $(hash); if ($targetAnswer.length === 0) return; // 1. 展开答案:设置 display + transition + data 属性 $targetAnswer .css({ 'display': 'block', 'transition': 'all 300ms ease-in' }) .data('slide-toggle', true); // 2. 同步更新对应问题项的 aria-expanded 和 tabindex const controlId = hash.substring(1); // e.g., "faq-0" const $trigger = $(`[aria-controls="${controlId}"]`); if ($trigger.length) { $trigger .attr('aria-expanded', 'true') .attr('tabindex', '0'); // 确保键盘可聚焦 } // 3. 平滑滚动至问题项(提升 UX) const $scrollTarget = $trigger.length ? $trigger : $targetAnswer; $scrollTarget[0]?.scrollIntoView?.({ behavior: 'smooth', block: 'center' }); }, 100); } }; })(jQuery, Drupal);? 关键注意事项:
- 执行时机:使用 setTimeout(..., 100) 是因 Drupal Behaviors 可能在 DOM 就绪前触发;若在非 Drupal 环境,建议改用 $(document).ready() 或 DOMContentLoaded。
- ARIA 同步不可省略:仅展开答案而不更新 aria-expanded="true" 会破坏可访问性,屏幕阅读器将无法感知状态变化。
- 避免重复触发:该逻辑只在页面首次加载时执行(不监听 hashchange),防止用户手动修改 URL 时意外重复展开。
- CSS 兼容性:确保答案项无 !important 覆盖内联样式;若存在,可改用 addClass('is-expanded') 配合 CSS 规则(推荐长期维护方案)。
? 进阶建议(推荐生产环境采用):
将展示逻辑抽离为 CSS 类,例如:.list--faq li[id^="faq-"].is-expanded { display: block !important; transition: all 300ms ease-in; }然后 JS 中仅操作类名:
$targetAnswer.addClass('is-expanded'); $trigger.attr('aria-expanded', 'true');此举更利于主题定制、减少内联样式污染,也便于后续添加动画钩子(如 @keyframes)。
通过以上方案,您不仅能精准响应 URL 锚点,还能保障无障碍支持、视觉动效与语义结构的一致性——让每个直达链接都成为一次无缝、可信的用户服务入口。










