childNodes 不能直接按 HTML 层级缩进渲染,因为它包含文本、注释等非元素节点,换行符会被解析为 Text 节点,插入缩进会破坏 DOM 结构;应使用 children 递归遍历元素节点,结合 CSS padding-left 和 depth-N 类实现稳定缩进。

childNodes 为什么不能直接按 HTML 层级缩进渲染
因为 childNodes 包含文本节点、注释节点和元素节点,而换行缩进产生的空格和换行符会被解析为 Text 节点。如果你遍历 childNodes 并逐个插入缩进字符(比如 ),实际会破坏 DOM 结构——例如在 和其第一个 之间插入空格,可能让浏览器误判文本内容位置,导致样式错乱或事件绑定失效。
真正可控的缩进应基于元素层级深度,而非节点顺序。你需要的是递归遍历 children(只含元素节点),配合 CSS 的 margin-left 或 padding-left 控制视觉缩进。
-
childNodes是“原始输入”,children才是“结构骨架” - 嵌套列表常见于
,此时每个- …
的父级就是缩进锚点 - 用
node.children配合node.parentElement可安全推导层级,避免文本节点干扰
用递归函数计算并设置嵌套深度 class
给每个 添加 depth-N 类,再用 CSS 控制缩进,比直接操作 innerHTML 更稳定。关键不是“怎么缩进”,而是“怎么准确识别当前 在哪一层”。
下面这个函数能正确处理任意嵌套:
function markDepth(node, depth = 0) {
if (node.nodeType === Node.ELEMENT_NODE && node.tagName === 'LI') {
node.classList.add(`depth-${depth}`);
}
// 只向下递归 ul/ol 的子 li,跳过其他容器(如 div、p)
for (const child of node.children) {
if (child.tagName === 'UL' || child.tagName === 'OL') {
for (const li of child.children) {
if (li.tagName === 'LI') {
markDepth(li, depth + 1);
}
}
}
}
}
// 启动:从根 ul/ol 开始
markDepth(document.querySelector('ul'));
- 不依赖
childNodes,完全避开文本节点陷阱 - 只对
标记深度,不污染其他节点 - 遇到
或才增加深度,符合语义嵌套逻辑
CSS 缩进方案必须用 padding-left 而非 text-indent
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力:
- 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面;
- 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”;
- 提及位于 `apps/console/src/featurtext-indent 只缩进首行,对多行 (比如含
或换行)无效;而
padding-left 作用于整个盒模型,且可被 box-sizing: border-box 稳定控制。
推荐写法:
.depth-0 { padding-left: 0; }
.depth-1 { padding-left: 1.5em; }
.depth-2 { padding-left: 3em; }
.depth-3 { padding-left: 4.5em; }
- 用
em单位,缩进随字体大小自适应 - 避免用
px,否则响应式下易错位 - 不要用
margin-left,它会影响外边距折叠,且在 flex/grid 容器中行为不可控
编辑器中实时更新缩进时容易漏掉动态插入的节点
用户在富文本编辑器里粘贴或拖拽新增列表项时,新插入的 不会自动获得 depth-N 类。你得监听 DOM 变化,但不能无差别重跑全树标记——性能差,还可能破坏已有状态(如用户正在编辑的光标位置)。
- 监听
MutationObserver,只关注childList和subtree: true - 观察范围限定在已知列表容器(如
contenteditable区域内的ul, ol) - 新增节点后,只对新插入的
及其后代执行markDepth,传入其父级的深度 + 1 - 别忘了清理旧 class:新增
可能被移出原位置,原depth-N类需清除
缩进逻辑本身不难,难的是在编辑器这种频繁变更 DOM 的环境里,保持 class 和真实嵌套关系始终一致。一旦漏掉某次插入或移动,缩进就会错层,而且很难肉眼定位是哪一层崩了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










