appendChild()向ol添加li需先用createElement创建节点再插入,不能传字符串;插开头或中间用insertBefore(),参照节点为null时等效appendChild;批量添加应使用DocumentFragment避免多次重排。

用 appendChild() 向 ol 添加新 li 最直接
浏览器原生支持,无需框架,只要拿到 ol 元素和要插入的内容,就能立刻生效。关键不是“怎么加”,而是“加什么”——你得先创建一个合法的 li 元素节点,不能直接传字符串。
常见错误是写成:olElement.appendChild("新的项"),这会报错:TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'。字符串不是节点,必须用 document.createElement('li') 创建后再设内容。
- 用
document.createElement('li')创建节点 - 用
textContent或innerHTML填充内容(优先用textContent防 XSS) - 用
olElement.appendChild(newLi)插入
想插到开头或中间?改用 insertBefore()
appendChild() 只能追加到末尾。如果需要插入到第 1 个位置、或某个特定 li 之前,就得用 insertBefore()。它接收两个参数:要插入的节点 + 参照节点(即插在谁前面)。
比如插到最前面:olElement.insertBefore(newLi, olElement.firstElementChild);如果 ol 原本为空,firstElementChild 是 null,此时 insertBefore 会自动变成追加行为,不用额外判断。
立即学习“前端免费学习笔记(深入)”;
- 参照节点为
null时,等效于appendChild - 不要传错顺序:是
insertBefore(newNode, referenceNode),不是反过来 - 如果想插在第 2 个
li之后,就取第 3 个作为referenceNode,或用olElement.children[2]
批量添加多个 li?别循环调用 appendChild
一次加 10 个 li,如果写 10 次 appendChild,会触发 10 次 DOM 重排,性能明显变差。正确做法是用 DocumentFragment 中转:
const fragment = document.createDocumentFragment();
for (let i = 0; i < items.length; i++) {
const li = document.createElement('li');
li.textContent = items[i];
fragment.appendChild(li);
}
olElement.appendChild(fragment); // 仅一次真实 DOM 插入
DocumentFragment 不在真实 DOM 树中,操作它不触发渲染,适合组装节点。现代浏览器也支持用 append() 直接传多个节点:olElement.append(li1, li2, li3),但 IE 完全不支持,需按目标兼容范围决定。
注意 ol 的 start 属性和序号连续性
动态添加后,浏览器会自动更新序号显示,但前提是没手动干扰计数逻辑。如果你设置了 <ol start="5"></ol>,新插入的 li 仍会按自然顺序编号(如第 6、7 项),不会从 5 开始重算——start 只影响起始值,不影响后续自增。
真正容易出问题的是:用 CSS 把 li 的 list-style-type 改成 none 后又依赖伪元素生成序号,此时 JS 添加的 li 不会自动获得序号样式,得靠 CSS counter-increment 配合,否则序号“看起来”断了。
序号是否连续,不取决于 JS 怎么加,而取决于 HTML 结构是否保持 ol > li 的直系关系,以及有没有用内联 value 属性强行覆盖单个项的编号。



















