
本文介绍一种基于递归遍历的 JavaScript 方法,用于从具有嵌套 .child-elements-container 结构的 HTML 中,提取每个 div 元素的 id 及其子树结构,并组织为嵌套对象数组。
本文介绍一种基于递归遍历的 javascript 方法,用于从具有嵌套 `.child-elements-container` 结构的 html 中,提取每个 `div` 元素的 `id` 及其子树结构,并组织为嵌套对象数组。
在构建可折叠/嵌套的 UI 组件(如树形菜单、组织架构图或拖拽式表单设计器)时,常需将 DOM 层级关系映射为结构化数据。上述 HTML 展示了一种典型的递归容器模式:每个节点以 id 标识,其子元素被包裹在 <div class="child-elements-container"> 内——这正是递归解析的理想场景。
以下是一个简洁、健壮的递归函数实现:
const getChildren = (container) => {
// 获取当前容器下直接子级的 div(排除 .child-elements-container 自身)
const directDivs = container ? [...container.querySelectorAll(':scope > div:not(.child-elements-container)')] : [];
return directDivs.map(el => ({
id: el.id || null, // 若无 id,设为 null(建议确保 HTML 中所有目标 div 都有 id)
children: getChildren(el.querySelector('.child-elements-container'))
}));
};
// 从根容器开始解析
const root = document.querySelector('.child-elements-container');
const treeData = getChildren(root);
console.log(treeData);✅ 输出示例(对应题干 HTML):
[
{ "id": "116", "children": [] },
{
"id": "105",
"children": [
{ "id": "4", "children": [] }
]
}
]⚠️ 注意事项:
立即学习“前端免费学习笔记(深入)”;
- :scope > div:not(.child-elements-container) 确保只选取直接子 div 节点(即业务元素),跳过作为容器的 .child-elements-container 本身,避免误入嵌套层级;
- 函数默认忽略无 id 的元素;如需兼容性处理,可在 el.id || null 处扩展逻辑(例如生成临时 ID 或抛出警告);
- 若需反向查找(如:已知 id="4",定位其祖先 id="105"),可改用 el.closest('[id]') 配合循环向上遍历,而非本例的向下构建;
- 实际项目中建议增加类型校验与空值防护,例如 if (!container || !container.children.length) return [];。
该方法时间复杂度为 O(n)(n 为相关 DOM 节点总数),空间复杂度取决于最大嵌套深度,适用于中等规模树形结构的数据导出与状态同步场景。



















