如何将嵌套HTML ul/li结构转为JSON?Angular+jQuery求助
问题
我正在开发一款拖拽式表单构建器应用,采用Angular和jQuery技术栈。现有一个主<li>标签,其下包含嵌套的<li>和<ul>标签结构。根据应用需求,需将该结构转换为指定格式的JSON,我尝试使用递归函数但未成功,恳请提供帮助。
原始HTML结构
<li id="mainList" style="list-style: none;"> <div class="row"> <div class="col-md-12"> <ul class="sortable ui-sortable"> <li data-is-component="true" data-type-text="Text Field" data-type="1" data-element-id="n8b78496-04bd"> <div class="form-group builder-component mt-1"> <label style="font-size:smaller" for="exampleFormControlInput1">Text Field</label> <input type="email" class="form-control form-control-sm" placeholder="Text Field" disabled=""> </div> </li> <li data-is-component="true" data-type-text="Number" data-type="3" data-element-id="nbdbeecb-ff2d"> <div class="form-group builder-component mt-1"> <label style="font-size:smaller" for="exampleFormControlInput1">Number</label> <input type="email" class="form-control form-control-sm" placeholder="Number" disabled=""> </div> </li> <li id="n9cdfd2a-95ea" data-is-component="false" data-type-text="Column 2" data-type="60" data-element-id="n9cdfd2a-95ea"> <div class="row"> <div class="col-md-6"> <ul class="sortable ui-sortable"> <li data-is-component="true" data-type-text="Choice" data-type="5" data-element-id="n4488d94-bf63"> <div class="form-group builder-component mt-1"> <label style="font-size:smaller" for="exampleFormControlInput1">Choice</label> <input type="email" class="form-control form-control-sm" placeholder="Choice" disabled=""> </div> </li> </ul> </div> <div class="col-md-6"> <ul class="sortable ui-sortable"> <li data-is-component="true" data-type-text="Select Box" data-type="6" data-element-id="n1179190-213f"> <div class="form-group builder-component mt-1"> <label style="font-size:smaller" for="exampleFormControlInput1">Select Box</label> <input type="email" class="form-control form-control-sm" placeholder="Select Box" disabled=""> </div> </li> <li data-is-component="true" data-type-text="Date / Time" data-type="7" data-element-id="n2cd4518-633e"> <div class="form-group builder-component mt-1"> <label style="font-size:smaller" for="exampleFormControlInput1">Date / Time</label> <input type="email" class="form-control form-control-sm" placeholder="Date / Time" disabled=""> </div> </li> </ul> </div> </div> </li> <li data-is-component="true" data-type-text="Color" data-type="11" data-element-id="n6103ae8-67e4"> <div class="form-group builder-component mt-1"> <label style="font-size:smaller" for="exampleFormControlInput1">Color</label> <input type="email" class="form-control form-control-sm" placeholder="Color" disabled=""> </div> </li> </ul> </div> </div> </li>
期望生成的JSON格式
{ "id": "mainList", "childs": [{ "id": "n8b78496-04bd", "childs": null }, { "id": "nbdbeecb-ff2d", "childs": null }, { "id": "n9cdfd2a-95ea", "childs": [ [{ "id": "n4488d94-bf63", "childs": null }], [{ "id": "n1179190-213f", "childs": null }, { "id": "n2cd4518-633e", "childs": null }] ] }, { "id": "n6103ae8-67e4", "childs": null } ] }
解决方案
以下是基于jQuery的递归实现,可精准将目标HTML结构转换为指定格式的JSON:
function convertToJson($element) { const result = { id: $element.attr('id') || $element.data('element-id'), childs: null }; // 处理列容器类型(非组件) if ($element.data('is-component') === false) { const columns = []; // 遍历每个列下的排序列表 $element.find('.row > [class^="col-md-"]').each(function() { const columnItems = []; $(this).find('ul.sortable > li').each(function() { columnItems.push(convertToJson($(this))); }); columns.push(columnItems); }); result.childs = columns; } else { // 处理组件类型,检查是否包含子列表 const childUl = $element.find('ul.sortable'); if (childUl.length > 0) { const childItems = []; childUl.find('> li').each(function() { childItems.push(convertToJson($(this))); }); result.childs = childItems; } } return result; } // 调用示例 const mainList = $('#mainList'); const formJson = convertToJson(mainList); console.log(JSON.stringify(formJson, null, 2));
代码说明
- 递归核心逻辑:针对每个
<li>元素,根据data-is-component属性区分处理:- 非组件(列容器):遍历其下的
col-md-*列,将每列内的组件转换为子数组,最终组成二维数组作为childs值。 - 组件类型:若存在子
ul.sortable则递归处理子元素,否则childs设为null。
- 非组件(列容器):遍历其下的
- ID匹配规则:优先获取元素的
id属性,若不存在则使用data-element-id,完全匹配示例中的ID取值逻辑。 - Angular适配:如果需要在Angular环境中使用,可将此逻辑封装为服务,或者改用原生JavaScript实现(DOM操作逻辑一致,仅API调用方式不同)。
内容的提问来源于stack exchange,提问作者atalay
相关产品推荐
相关产品推荐

