根据你的具体需求(追加子元素、追加到特定位置、追加 HTML 字符串),有 5 种主流方法,区别很大:
1. 现代首选:append() 和 prepend()(推荐)
这是目前最灵活、最易用的方法,可以同时追加多个节点或文本,且会自动处理字符串。
const parent = document.getElementById('container');
parent.append('Hello ', 'World');
const newDiv = document.createElement('div');
newDiv.textContent = '我是新来的';
parent.append(newDiv); 注:prepend() 用法相同,但会把新节点插到父元素的最前面。
2. 传统标准:appendChild()(经典)
只能追加单个节点,且追加字符串会报错(必须用 createTextNode 包裹)。
const parent = document.getElementById('container');
const newP = document.createElement('p');
newP.textContent = '传统方法';
parent.appendChild(newP); ⚠️ 注意:如果追加的节点已在 DOM 中存在,它会剪切(移动)而非复制。
3. 追加 HTML 字符串:insertAdjacentHTML()(高性能)
如果你有一大串 HTML 标签字符串,用这个方法最高效(避免销毁原有元素的事件监听)。
const parent = document.getElementById('container');
parent.insertAdjacentHTML('beforeend', '<div class="item">插入的HTML内容</div>');想让字符串变 DOM 元素,也可以用 innerHTML += '...',但强烈不推荐,它会重绘整个父容器,导致性能浪费和事件丢失。
4. 移动/剪切现有 DOM 节点
当使用 appendChild() 或 append() 操作页面上已有的元素时,该元素会从原位置消失,跑到新位置(类似于“剪切”操作)。
const existingDiv = document.querySelector('.old-position');
document.querySelector('.new-parent').appendChild(existingDiv);
5. 批量追加:DocumentFragment(性能最优)
如果你要循环追加 1000 个 li,直接循环操作 DOM 会引发多次重排。推荐用文档片段容器缓存:
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const li = document.createElement('li');
li.textContent = i;
fragment.appendChild(li);
}
document.getElementById('list').appendChild(fragment);
速查对比表(帮你避坑)
| 方法 | 参数类型 | 返回值 | 能否批量 | 是否剪切现有节点 |
|---|
append() | 节点 / 字符串 | undefined | ✅ 可以(逗号分隔) | ❌ 不会(会自动克隆逻辑,但通常视为移动) 实际上标准 append 若传入已存在节点,会移动它。注意:它不会克隆。更正:若传入现有引用,会移动。 |
appendChild() | 仅节点 | 追加的节点 | ❌ 不可以 | ✅ 会移动 |
insertAdjacentHTML | 字符串 | undefined | ✅ (拼接字符串) | ❌ 不涉及节点移动 |
innerHTML += | 字符串 | undefined | ✅ | ❌ 但会销毁重建所有子元素 |
最佳实践建议
日常增删:直接用 parent.append(child) 最省事。
插入复杂模板:用 insertAdjacentHTML。
大列表渲染:必须用 DocumentFragment 或模板引擎。
注意:如果你想复制一个已存在的节点而不是移动它,记得先调用 cloneNode(true) 再追加。