DOM 元素增删改
创建新元素、插入到页面、删除不需要的元素——这些操作让页面能动态响应数据变化,而无须刷新页面。
创建元素
createElement() — 创建元素节点
javascript
const div = document.createElement('div');
div.textContent = '我是动态创建的';
div.className = 'box';
div.id = 'dynamic-1';
document.write(div.outerHTML); html
<div id="output"></div> 此时元素只存在于内存中,还没有出现在页面上——需要显式插入。
createTextNode() — 创建文本节点
javascript
const textNode = document.createTextNode('文本内容');
// 通常直接用 textContent 更简单 插入节点
appendChild() — 追加到末尾
javascript
const newItem = document.createElement('li');
newItem.textContent = '新项目';
const list = document.querySelector('ul');
list.appendChild(newItem); html
<ul><li>项目1</li><li>项目2</li></ul> insertBefore() — 插入到指定位置之前
javascript
const list = document.querySelector('ul');
const firstItem = list.querySelector('li');
const newItem = document.createElement('li');
newItem.textContent = '插入到第一个';
list.insertBefore(newItem, firstItem); html
<ul><li>原有项目</li><li>项目2</li><li>项目3</li></ul> append() / prepend() — 现代方法(推荐)
javascript
function makeItem(text) {
const li = document.createElement('li');
li.textContent = text;
return li;
}
const list = document.querySelector('ul');
list.append('纯文本也可以', makeItem('新项目'));
list.prepend(makeItem('第一个')); html
<ul><li>中间项目</li></ul> before() / after() — 元素外部插入
javascript
function makeItem(text) {
const li = document.createElement('li');
li.textContent = text;
return li;
}
const target = document.querySelector('.target');
target.before(makeItem('前面'));
target.after(makeItem('后面')); html
<div class="target" style="border:1px solid #ccc;padding:8px">目标元素</div> 删除节点
javascript
const item = document.querySelector('li');
item.parentNode.removeChild(item);
const secondItem = document.querySelector('li');
secondItem.remove(); html
<ul><li>项目A</li><li>项目B</li><li>项目C</li></ul> 清空元素
javascript
const container = document.querySelector('.container');
container.innerHTML = ''; html
<div class="container">
<p>段落1</p>
<p>段落2</p>
<p>段落3</p>
</div> 或逐个删除(避免 innerHTML 的性能和安全问题):
javascript
while (container.firstChild) {
container.firstChild.remove();
} 替换和克隆
replaceWith() — 替换元素
javascript
const oldElement = document.querySelector('.old');
const newElement = document.createElement('div');
newElement.textContent = '新内容';
oldElement.replaceWith(newElement); html
<div class="old">旧内容</div> cloneNode() — 克隆元素
javascript
const original = document.querySelector('.template');
const clone = original.cloneNode(true);
const shallow = original.cloneNode(false);
clone.querySelector('.title').textContent = '副本的标题';
document.querySelector('#clone-output').appendChild(clone); html
<div class="template">
<p class="title">原始标题</p>
<p>内容</p>
</div>
<div id="clone-output"></div> cloneNode(true) 深克隆会复制所有子元素,非常适合模板化渲染。但注意克隆不会复制通过 addEventListener 绑定的事件监听器——需要为克隆后的元素重新绑定。
文档片段(DocumentFragment)
当需要批量插入大量元素时,使用 DocumentFragment 作为临时容器,最后一次性插入 DOM——减少回流,提升性能:
javascript
const fragment = document.createDocumentFragment();
const items = ['项目A', '项目B', '项目C', '项目D'];
for (const name of items) {
const li = document.createElement('li');
li.textContent = name;
fragment.appendChild(li);
}
document.querySelector('ul').appendChild(fragment); html
<ul></ul> 正常流程中,每插入一个元素浏览器就可能触发一次回流(reflow)。DocumentFragment 在内存中构建好所有元素,一次性添加到 DOM,只触发一次回流。对于几十个元素的批量插入,差异不大;但对于成百上千的元素,性能提升显著。
综合示例:Todo 列表
javascript
let todoId = 0;
function addTodo(text) {
const li = document.createElement('li');
li.className = 'todo-item';
li.dataset.id = todoId++;
li.innerHTML = `
<span>${text}</span>
<button class="delete-btn">删除</button>
`;
// 为删除按钮绑定事件(每个按钮独立绑定)
li.querySelector('.delete-btn').addEventListener('click', () => {
li.remove();
});
document.querySelector('#todo-list').appendChild(li);
}
// 使用
addTodo('学习 JavaScript');
addTodo('练习 DOM 操作');
document.querySelector('#add-btn').addEventListener('click', () => {
const input = document.querySelector('#todo-input');
if (input.value.trim()) {
addTodo(input.value);
input.value = '';
}
}); html
<input id="todo-input" type="text" placeholder="输入待办事项">
<button id="add-btn">添加</button>
<ul id="todo-list"></ul> 这个简单示例涵盖了本章所有核心知识点——创建、插入、删除、事件绑定。