Semantic-UI Accordion动态插入元素失败?JSON驱动懒加载实现咨询
Semantic UI 多级Accordion JSON懒加载实现指南
原代码失效的核心原因
- 上下文取值错误:Semantic UI的
onOpen回调内,this指向的是被点击的.title元素,原代码直接拿$(this).attr('id')取值会得到空值,根本匹配不到对应的content容器。 - 结构嵌套不符合组件规范:原代码直接把子级的
.title和.content零散平铺在父级content内部,Semantic UI要求嵌套层级的手风琴必须用独立的.ui.accordion容器包裹,否则组件无法识别子层级的交互逻辑。 - 无重复渲染控制:没有标记已加载的节点,每次展开都会循环append重复结构,导致DOM冗余、交互错乱。
- 组件刷新时机错误:在循环插入每个节点时就反复调用
accordion('refresh'),会打断组件的状态同步,导致交互失效。
修正后的可运行实现
核心逻辑说明
完全按照Semantic UI的嵌套规则生成DOM结构,通过唯一层级id建立DOM节点和JSON数据的映射,在节点首次展开时才插入对应子内容,实现全层级的懒加载。
参考代码
直接使用如下脚本替换原有代码即可:
// 直接引用Python生成的非严格格式JS对象即可 const jsonData = { 'A' : { 'A1':{'A12':[]}, 'A2': [], 'A3': [], }, 'B' : { 'B1':[], 'B2': [], 'B3': {'B31':[]}, }, 'C' : { 'C1':[] } } $(document).ready(function(){ // 初始化根节点手风琴 $('.ui.accordion').accordion({ onOpen: function() { // 正确关联当前触发展开的title和对应的content块 const $triggerTitle = $(this); const $targetContent = $triggerTitle.next('.content'); const currentNodeKey = $targetContent.attr('id'); // 已加载过的节点直接跳过,避免重复插入 if ($targetContent.data('loaded')) return; // 取当前节点对应的子JSON数据 const childNodes = jsonData[currentNodeKey]; // 无子数据时标记为已加载,直接退出 if (!childNodes || (Array.isArray(childNodes) && childNodes.length === 0)) { $targetContent.data('loaded', true); return; } // 在当前content内部生成独立的子手风琴容器 const $childAccWrap = $('<div class="ui styled accordion"></div>'); // 遍历子节点生成符合规范的结构 Object.keys(childNodes).forEach(childKey => { // 生成带层级的唯一id,保证深层节点id不冲突 const childNodeId = `${currentNodeKey}-${childKey}`; // 写入子节点结构 $childAccWrap.append(` <div class="title"> <i class="dropdown icon"></i> ${childKey} </div> <div class="content" id="${childNodeId}"></div> `); // 建立子节点id和对应JSON数据的映射,供后续展开时调用 jsonData[childNodeId] = childNodes[childKey]; }); // 把子级手风琴整体插入当前content $targetContent.append($childAccWrap); // 标记当前节点已完成加载 $targetContent.data('loaded', true); // 等DOM渲染完成后统一刷新组件状态,绑定子级手风琴的交互事件 $targetContent.find('.ui.accordion').accordion('refresh'); } }); });
原有的基础HTML结构不需要修改,保持如下即可:
<div class="ui styled accordion"> <div class="title"> <i class="dropdown icon"></i> A </div> <div class="content" id="A"></div> <div class="title"> <i class="dropdown icon"></i> B </div> <div class="content" id="B"></div> <div class="title"> <i class="dropdown icon"></i> C </div> <div class="content" id="C"></div> </div>
运行效果说明
- 初始加载仅渲染顶层节点,无提前加载深层内容的性能损耗
- 任意层级节点首次展开时,自动生成对应的子手风琴结构,自动绑定展开交互
- 支持无限层级的递归渲染,完全匹配传入JSON的嵌套结构
- 已加载过的节点不会重复插入内容,展开收起的交互流畅稳定
内容的提问来源于stack exchange,提问作者zester
相关产品推荐
相关产品推荐

