JavaScript常用DOM API研究详解02:createElement、createTextNode、appendChild、removeChild、replaceChild
在Web开发中,操作DOM(文档对象模型)是前端开发者的核心工作之一。JavaScript提供了丰富的DOM API,允许动态地创建、修改和删除页面元素。本篇文章将深入研究以下五个常用的DOM方法:
createElement()
createTextNode()
appendChild()
removeChild()
replaceChild()
通过对这些方法的详细介绍和示例,将了解如何使用JavaScript来操作网页的结构和内容。
一、createElement()
方法
1.1 方法简介
createElement()
方法用于创建指定的HTML元素。这是动态添加新元素的第一步,通过此方法可以创建任何有效的HTML标签。
1.2 语法
const element = document.createElement(tagName);
tagName
:字符串,表示要创建的元素的标签名称,例如'div'
、'p'
、'span'
等。
1.3 返回值
- 返回一个新的DOM元素对象,类型为
HTMLElement
。
1.4 示例
示例1:创建一个div
元素
const newDiv = document.createElement('div');
console.log(newDiv); // 输出:<div></div>
示例2:创建一个带有属性的元素
const newButton = document.createElement('button');
newButton.type = 'button';
newButton.id = 'myButton';
newButton.className = 'btn btn-primary';
console.log(newButton); // 输出:<button type="button" id="myButton" class="btn btn-primary"></button>
1.5 注意事项
- 创建的元素在被添加到DOM之前,存在于内存中,不会显示在页面上。
tagName
不区分大小写,但按照惯例,HTML标签名称使用小写字母。
二、createTextNode()
方法
2.1 方法简介
createTextNode()
方法用于创建包含指定文本的文本节点。文本节点是DOM树中的叶节点,用于存储纯文本。
2.2 语法
const textNode = document.createTextNode(data);
data
:字符串,要在文本节点中显示的文本内容。
2.3 返回值
- 返回一个新的文本节点对象,类型为
Text
。
2.4 示例
示例1:创建一个简单的文本节点
const text = document.createTextNode('Hello, World!');
console.log(text); // 输出:"Hello, World!" 的文本节点
示例2:创建包含特殊字符的文本节点
const specialText = document.createTextNode('<script>alert("XSS")</script>');
console.log(specialText); // 输出:包含特殊字符的文本节点,浏览器不会解析其中的HTML或脚本
2.5 注意事项
- 文本节点中的内容不会被解析为HTML或脚本,所有字符都将被视为纯文本。
- 为了在元素中添加文本内容,通常需要先创建元素节点,再将文本节点作为子节点添加到元素中。
三、appendChild()
方法
3.1 方法简介
appendChild()
方法用于将一个节点添加为指定父节点的最后一个子节点。此方法是将新创建的元素或文本节点插入到DOM中的主要方式。
3.2 语法
parentNode.appendChild(newNode);
parentNode
:目标父节点,类型为Node
。newNode
:要添加的节点,类型为Node
。
3.3 返回值
- 返回被添加的节点
newNode
。
3.4 示例
示例1:将新元素添加到页面
const newParagraph = document.createElement('p');
const text = document.createTextNode('这是一个新段落。');
newParagraph.appendChild(text);
const body = document.querySelector('body');
body.appendChild(newParagraph);
结果:页面的<body>
中添加了一个新的<p>
元素,内容为“这是一个新段落。”
示例2:添加多个子节点
const list = document.createElement('ul');
const items = ['苹果', '香蕉', '橘子'];
items.forEach((item) => {
const listItem = document.createElement('li');
listItem.textContent = item;
list.appendChild(listItem);
});
document.body.appendChild(list);
结果:页面上添加了一个列表,包含三个水果名称。
3.5 注意事项
- 如果
newNode
已经存在于DOM中,调用appendChild()
会将其从原来的位置移动到新的位置,而不是创建副本。 appendChild()
只能添加节点类型的对象,不能直接添加字符串。
四、removeChild()
方法
4.1 方法简介
removeChild()
方法用于从DOM中删除指定的子节点。
4.2 语法
removedNode = parentNode.removeChild(childNode);
parentNode
:父节点,类型为Node
。childNode
:要删除的子节点,类型为Node
。
4.3 返回值
- 返回被删除的节点
childNode
。
4.4 示例
示例1:删除指定的元素
const parent = document.getElementById('list');
const child = document.getElementById('item2');
parent.removeChild(child);
结果:ID为item2
的元素被从父元素中移除。
示例2:删除第一个子节点
const list = document.querySelector('ul');
const firstItem = list.firstChild;
list.removeChild(firstItem);
4.5 注意事项
childNode
必须是parentNode
的直接子节点,否则会抛出NotFoundError
。- 删除节点后,节点仍然存在于内存中,可以重新添加到DOM中。
五、replaceChild()
方法
5.1 方法简介
replaceChild()
方法用于用一个新节点替换指定的子节点。
5.2 语法
replacedNode = parentNode.replaceChild(newChild, oldChild);
parentNode
:父节点,类型为Node
。newChild
:要插入的新节点,类型为Node
。oldChild
:要被替换的现有子节点,类型为Node
。
5.3 返回值
- 返回被替换的节点
oldChild
。
5.4 示例
示例1:替换一个元素
const oldItem = document.getElementById('item3');
const newItem = document.createElement('li');
newItem.textContent = '新项目';
const list = document.getElementById('list');
list.replaceChild(newItem, oldItem);
结果:ID为item3
的列表项被新的列表项替换。
示例2:替换文本节点
const paragraph = document.querySelector('p');
const newText = document.createTextNode('替换后的文本内容。');
paragraph.replaceChild(newText, paragraph.firstChild);
5.5 注意事项
newChild
如果已经存在于DOM中,会先从原位置移除,再插入到新位置。oldChild
必须是parentNode
的直接子节点,否则会抛出NotFoundError
。
六、综合示例
6.1 动态创建并添加元素
假设我们想在页面上创建一个带有链接的列表。
// 创建<ul>元素
const list = document.createElement('ul');
// 定义链接数据
const links = [
{ href: 'https://www.google.com', text: 'Google' },
{ href: 'https://www.facebook.com', text: 'Facebook' },
{ href: 'https://www.twitter.com', text: 'Twitter' },
];
// 创建列表项并添加到列表中
links.forEach((link) => {
const listItem = document.createElement('li');
const anchor = document.createElement('a');
anchor.href = link.href;
anchor.textContent = link.text;
listItem.appendChild(anchor);
list.appendChild(listItem);
});
// 将列表添加到页面
document.body.appendChild(list);
结果:页面上显示一个包含三个链接的无序列表。
6.2 动态修改元素
假设我们有一个待办事项列表,需要在用户完成任务时将其从列表中移除。
<ul id="todoList">
<li id="task1">完成报告</li>
<li id="task2">参加会议</li>
<li id="task3">整理文件</li>
</ul>
// 用户完成了任务2,需要移除它
const todoList = document.getElementById('todoList');
const task2 = document.getElementById('task2');
todoList.removeChild(task2);
结果:任务2从列表中移除。
6.3 替换元素
假设我们需要将旧的联系方式替换为新的联系方式。
<div id="contactInfo">
<p>Email: old@example.com</p>
</div>
const contactDiv = document.getElementById('contactInfo');
const oldContact = contactDiv.querySelector('p');
const newContact = document.createElement('p');
newContact.textContent = 'Email: new@example.com';
contactDiv.replaceChild(newContact, oldContact);
结果:联系方式被更新为新的邮箱地址。
七、注意事项和最佳实践
7.1 避免多次重排和重绘
在操作DOM时,频繁地添加、删除或修改元素会导致页面的重排(Reflow)和重绘(Repaint),影响性能。为了优化性能,可以:
-
使用文档片段(DocumentFragment):先将多个新元素添加到文档片段中,再一次性添加到DOM中。
const fragment = document.createDocumentFragment(); for (let i = 0; i < 100; i++) { const div = document.createElement('div'); div.textContent = `元素 ${i}`; fragment.appendChild(div); } document.body.appendChild(fragment);
7.2 操作节点的副本
在某些情况下,可能需要操作节点的副本而不是直接操作DOM,可以使用cloneNode()
方法。
const originalNode = document.getElementById('original');
const clonedNode = originalNode.cloneNode(true); // 参数true表示深度克隆
7.3 检查节点关系
在使用removeChild()
或replaceChild()
时,确保节点之间的父子关系正确。
if (parentNode.contains(childNode)) {
parentNode.removeChild(childNode);
}
八、总结
createElement()
:创建新的元素节点。createTextNode()
:创建新的文本节点。appendChild()
:将节点添加为父节点的最后一个子节点。removeChild()
:从父节点中移除指定的子节点。replaceChild()
:用新节点替换父节点中的指定子节点。
九、参考资料
- MDN Web Docs - Document.createElement()
- MDN Web Docs - Document.createTextNode()
- MDN Web Docs - Node.appendChild()
- MDN Web Docs - Node.removeChild()
- MDN Web Docs - Node.replaceChild()
- JavaScript高级程序设计(第4版)