在JavaScript的DOM操作中,动态创建页面元素是开发过程中经常遇到的需求,appendChild和innerHTML是两种最常用的实现方式,两者在功能上有重叠但也有明显差异,理解这些差异能帮助开发者写出更合理的代码。

一、使用appendChild创建元素
appendChild是DOM节点的方法,用于将一个节点添加到指定父节点的子节点列表的末尾。使用它创建元素需要先通过document.createElement方法创建元素节点,再将其添加到目标父节点中。
基础用法示例
// 获取父容器
const parent = document.getElementById('container');
// 创建新的div元素
const newDiv = document.createElement('div');
// 设置元素内容和属性
newDiv.textContent = '这是通过appendChild创建的元素';
newDiv.className = 'new-item';
// 将新元素添加到父容器末尾
parent.appendChild(newDiv);
如果要创建包含多层嵌套结构的元素,需要逐层创建节点再依次添加:
const parent = document.getElementById('list');
// 创建li元素
const li = document.createElement('li');
// 创建span子元素
const span = document.createElement('span');
span.textContent = '子元素内容';
// 将span添加到li中
li.appendChild(span);
// 将li添加到父列表
parent.appendChild(li);
二、使用innerHTML创建元素
innerHTML是DOM元素的属性,用于获取或设置元素内部的HTML内容。通过设置innerHTML可以直接写入HTML字符串,浏览器会自动解析字符串并生成对应的DOM节点。
基础用法示例
const parent = document.getElementById('container');
// 直接设置innerHTML添加新元素
parent.innerHTML += '<div class="new-item">这是通过innerHTML创建的元素</div>';
如果要创建复杂嵌套结构,直接用HTML字符串拼接会更简洁:
const parent = document.getElementById('list');
// 拼接HTML字符串添加嵌套元素
parent.innerHTML += '<li><span>子元素内容</span></li>';
三、appendChild和innerHTML的核心区别
1. 对原有内容的处理方式
appendChild只会将新节点添加到父节点的子节点列表末尾,不会影响父节点原有的其他子节点。
而innerHTML如果直接赋值(不使用+=),会完全替换掉元素原有的所有内部内容;如果使用+=拼接,本质是先获取原有innerHTML字符串,拼接新字符串后再重新赋值,会先销毁原有所有子节点再重新创建,原有节点上绑定的事件也会丢失。
2. 性能表现差异
当只需要添加少量元素时,两者性能差异不明显。但如果需要批量添加大量元素,appendChild的性能通常优于innerHTML:
- appendChild添加节点时,只会创建和插入新节点,不会处理原有节点
- innerHTML使用+=拼接时,会先序列化原有所有子节点为字符串,拼接后再解析整个字符串重新生成所有节点,DOM操作开销更大
如果要用innerHTML批量添加元素,可以先拼接好所有HTML字符串,再一次性赋值,性能会接近appendChild:
const parent = document.getElementById('list');
let htmlStr = '';
// 批量拼接HTML字符串
for (let i = 0; i < 100; i++) {
htmlStr += `<li>第${i}项</li>`;
}
// 一次性赋值,减少重绘重排
parent.innerHTML = htmlStr;
3. 事件绑定的影响
appendChild添加的元素,如果是先创建节点再绑定事件,事件会正常生效;如果是原有节点上已经绑定的事件,不会被影响。
innerHTML重新赋值后,原有子节点会被销毁,原来绑定在原有节点上的事件也会随之失效,新添加的节点需要重新绑定事件,或者在父节点上使用事件委托。
4. 安全性差异
appendChild创建节点时,内容是通过textContent或者逐层创建节点设置的,不会出现HTML注入的问题,安全性更高。
innerHTML会直接解析HTML字符串,如果字符串中包含用户输入的内容,且没有做转义处理,就可能出现XSS攻击风险:
// 危险示例:用户输入的内容直接放入innerHTML
const userInput = '<img src="x" onerror="alert('恶意代码')">';
document.getElementById('container').innerHTML = userInput; // 会执行恶意代码
5. 使用便捷性差异
appendChild创建复杂嵌套结构时,需要逐层创建节点并添加,代码量更多,写起来更繁琐。
innerHTML直接写HTML字符串就可以创建嵌套结构,代码更简洁,更符合前端开发者写HTML的习惯,开发效率更高。
四、两者的适用场景
| 场景 | 推荐方式 | 原因 |
|---|---|---|
| 添加少量简单元素,且需要保留原有节点事件 | appendChild | 不影响原有内容,事件不会丢失 |
| 批量添加大量元素 | appendChild或一次性innerHTML赋值 | 性能更优,避免重复解析DOM |
| 创建复杂嵌套的HTML结构 | innerHTML(一次性赋值) | 代码更简洁,开发效率高 |
| 内容包含用户输入,需要防范XSS | appendChild | 天然避免HTML注入风险 |
| 需要替换元素原有全部内容 | innerHTML直接赋值 | 操作更直接,代码更简洁 |
五、总结
appendChild和innerHTML都是JavaScript中创建元素的有效方式,没有绝对的好坏之分,只有适用场景的不同。开发时可以根据需求选择:如果注重性能和安全性,或者需要保留原有节点状态,优先选择appendChild;如果需要快速创建复杂HTML结构,且内容可控,使用innerHTML会更高效。理解两者的核心差异,才能在实际开发中做出更合理的选择。
JavaScriptappendChildinnerHTML创建元素DOM操作修改时间:2026-07-10 20:51:31