自定义元素实现内容折叠组件需继承htmlelement、创建shadow dom并管理open状态,支持max-height动画、属性/事件通信、插槽注入及无障碍访问。

用自定义元素(Custom Element)实现内容折叠与展开组件,核心是封装可复用、语义清晰、支持开闭状态管理的 Web Component。它比原生 <details></details> 更灵活,能统一控制样式、动画、事件和 API,适合中大型项目或设计系统集成。
定义基础结构与生命周期
自定义元素需继承 HTMLElement,在 constructor 中初始化 Shadow DOM,并在 connectedCallback 中渲染默认结构(含标题栏和内容区)。关键点:
- 使用
this.attachShadow({ mode: 'open' })隔离样式,避免全局污染 - 标题区域绑定点击事件,触发切换逻辑;内容区域默认设
display: none或max-height: 0 - 通过
attributeChangedCallback响应open属性变化(如<my-collapse open></my-collapse>),实现属性驱动状态
状态管理与切换逻辑
折叠/展开本质是控制内容区域的可见性与过渡效果。推荐用 max-height + overflow: hidden 实现平滑动画(比 display 更易过渡):
- 初始状态:
max-height: 0; padding: 0; opacity: 0 - 展开时:计算内容实际高度(
scrollHeight),设为max-height,并恢复padding和opacity - 收起完成后再设
display: none(可选),提升渲染性能 - 提供
toggle()、open()、close()方法供外部调用
支持属性与事件通信
让组件真正“可配置”,需暴露标准接口:
-
属性:支持
open(布尔值,控制初始状态)、disabled(禁用交互)、transition(是否启用动画) -
事件:派发
collapse-open和collapse-close自定义事件,携带detail: { target: this },便于父组件监听 -
插槽:用
<slot name="header"></slot>和<slot name="content"></slot>分离标题与内容,支持任意 HTML 内容注入
样式与无障碍增强
原生体验不能妥协:
- 标题元素设
role="button"、aria-expanded和aria-controls,确保屏幕阅读器识别 - 键盘支持:监听
Enter和Space键触发切换 - 图标旋转动画用
transform: rotate()配合transition,避免影响布局流 - 默认样式用 CSS 变量(如
--collapse-bg、--collapse-border)方便主题定制











