DOM 元素增删改
创建新元素、插入到页面、删除不需要的元素——这些操作让页面能动态响应数据变化,而无须刷新页面。
创建元素
createElement() — 创建元素节点
javascript
const div = document.createElement('div');
div.textContent = '我是动态创建的';
div.className = 'box';
div.id = 'dynamic-1'; 此时元素只存在于内存中,还没有出现在页面上——需要显式插入。
createTextNode() — 创建文本节点
javascript
const textNode = document.createTextNode('文本内容');
// 通常直接用 textContent 更简单 插入节点
appendChild() — 追加到末尾
javascript
const newItem = document.createElement('li');
newItem.textContent = '新项目';
const list = document.querySelector('ul');
list.appendChild(newItem); // 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); // 在 firstItem 之前插入 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('第一个')); before() / after() — 元素外部插入
javascript
const target = document.querySelector('.target');
target.before(makeItem('前面'));
target.after(makeItem('后面')); 删除节点
javascript
// 方式一:父元素删除子元素
const item = document.querySelector('li');
item.parentNode.removeChild(item);
// 方式二:自我删除(推荐)
const item = document.querySelector('li');
item.remove(); 清空元素
javascript
const container = document.querySelector('.container');
container.innerHTML = ''; // 简单粗暴
// 或逐个删除(避免 innerHTML 的性能和安全问题)
while (container.firstChild) {
container.firstChild.remove();
} 替换和克隆
javascript
// 替换
const oldElement = document.querySelector('.old');
const newElement = document.createElement('div');
newElement.textContent = '新内容';
oldElement.replaceWith(newElement);
// 克隆
const original = document.querySelector('.template');
const clone = original.cloneNode(true); // true = 深克隆(含子元素)
const shallow = original.cloneNode(false); // false = 浅克隆(仅元素本身)
// 修改克隆后插入
clone.querySelector('.title').textContent = '副本的标题';
document.body.appendChild(clone); 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); 正常流程中,每插入一个元素浏览器就可能触发一次回流(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> 这个简单示例涵盖了本章所有核心知识点——创建、插入、删除、事件绑定。