
本文介绍一种基于递归的 JavaScript 方法,将任意深度的嵌套 <ul><li> 结构(含 operator/condition 语义类)精准转换为保持层级关系的嵌套数组,如 [operator1, [operator2, [condition1], [condition2]], [condition3]]。
本文介绍一种基于递归的 javascript 方法,将任意深度的嵌套 `
- ` 结构(含 operator/condition 语义类)精准转换为保持层级关系的嵌套数组,如 `[operator1, [operator2, [condition1], [condition2]], [condition3]]`。
在前端开发中,常需将 DOM 中的嵌套列表结构序列化为便于传输或处理的 JavaScript 数据结构。关键挑战在于:既要忠实还原 <li> 的文本内容,又要严格保留 <ul> 所定义的嵌套层级——尤其当 class="operator" 的 <li> 可能自身包含子 <ul>,而 class="condition" 的 <li> 总是叶节点时,需通过 DOM 层级而非仅靠 class 判断结构。
以下是一个健壮、可复用的递归解析函数:
function parseNestedUl(element) { const result = []; // 遍历直接子元素(避免 querySelectorAll('li') 跨层级误匹配) for (const child of element.children) { if (child.tagName === 'LI') { const text = child.textContent.trim(); const nestedUl = child.querySelector('ul'); if (nestedUl) { // operator 节点:文本 + 展开的子数组(递归结果) const subArray = parseNestedUl(nestedUl); result.push([text, ...subArray]); } else { // condition 或无子列表的 operator:直接推入文本 result.push(text); } } } return result; }使用示例(需确保 DOM 已加载):
document.addEventListener('DOMContentLoaded', () => { const rootUl = document.querySelector('ul'); const nestedArray = parseNestedUl(rootUl); console.log(nestedArray); // 输出: ["operator1", ["operator2", ["condition1", "condition2"], "condition3"]] });⚠️ 注意事项:
立即学习“前端免费学习笔记(深入)”;
- HTML 结构必须合法:嵌套 <ul> 必须位于 <li> 内部(如示例中 operator1 后紧跟 <ul>),否则 querySelector('ul') 将无法正确定位子列表;
- 文本提取策略:使用 textContent.trim() 可安全获取纯文本(忽略子标签、空格、换行),若需保留 HTML 标签,请改用 innerHTML 并做 XSS 过滤;
- 性能提示:对超深嵌套(>100 层)需警惕栈溢出,生产环境可考虑改用迭代+栈模拟递归;
- 语义增强(可选):如需区分 operator 与 condition 类型,可在返回项中封装对象:{ type: 'operator', value: text, children: subArray }。
该方法不依赖外部库,兼容所有现代浏览器,且逻辑清晰、易于调试和扩展,是处理动态规则配置、可视化查询构建器等场景的理想基础工具。



















