讲解

找到节点之后,下一步是动态地创建、插入、移动、删除节点——这是所有交互界面的基本功。创建用 document.createElement('li') 造一个元素节点,设置好内容和属性后,用 append(尾部追加)、prepend(头部插入)、before/after(同级前后插入)挂到树上;元素从树上移除用 el.remove()。元素还可以整体移动:把一个已存在的节点 append 到别处,它会自动从原位置移走(一个节点在树上只有一个位置)。

批量插入的性能要点:逐个 append 会触发多次页面重排,大量节点应先放进 DocumentFragment(内存里的临时容器)一次性挂载,或拼好结构一次插入。现代 API(append、prepend、replaceChildren、remove)比老一套(appendChild、removeChild、insertBefore)语义直观得多,新项目直接用新的。

几个高频操作的速查:清空容器 list.replaceChildren()(比 innerHTML = '' 语义更清晰);克隆节点 el.cloneNode(true)(true 表示深拷贝子树);插入 HTML 片段用 insertAdjacentHTML('beforeend', html)(比改写 innerHTML 高效,不重建已有节点);判断元素是否在文档里 document.contains(el)。掌握了创建-配置-挂载这三板斧,配合上一章的查询,就能写出任何动态界面。

示例

<ul id="list">
  <li>原有事项</li>
</ul>
const list = document.querySelector('#list');

// 创建 → 配置 → 挂载
const item = document.createElement('li');
item.textContent = '新建事项';
item.classList.add('item');
item.dataset.id = '100';
list.append(item);

// 头部插入
const first = document.createElement('li');
first.textContent = '置顶事项';
list.prepend(first);

// 批量插入:先用 Fragment 攒好再一次挂载
const fragment = document.createDocumentFragment();
for (let i = 1; i <= 3; i++) {
  const li = document.createElement('li');
  li.textContent = '批量 ' + i;
  fragment.append(li);
}
list.append(fragment); // 只触发一次重排

// 移动已有节点:自动从原位置移走
list.append(first); // 「置顶事项」被移到了末尾

// 删除与清空
first.remove();
// list.replaceChildren(); // 一键清空

// 插入 HTML 片段(不重建已有节点)
list.insertAdjacentHTML('beforeend', '<li class="item">HTML 片段</li>');

// 克隆
const clone = item.cloneNode(true);
clone.textContent = '克隆的副本';
list.append(clone);

常见坑

  • 在循环里逐个 append 大量节点:每次都触发重排,页面明显卡顿。用 DocumentFragment 或一次性 innerHTML。
  • 以为 append 会复制节点:把已有节点 append 到别处是「移动」不是复制,要副本得 cloneNode(true)。
  • innerHTML += 追加内容:innerHTML += html 会把容器内所有节点销毁重建,绑定在子元素上的事件监听全部丢失。追加用 insertAdjacentHTML。
  • 删除后引用还在:el.remove() 只是从树上摘下,变量 el 仍持有节点;若上面挂着大数据或定时器,记得解除引用。

小结

createElement 造节点、append/prepend/before/after 挂树、remove 摘除、replaceChildren 清空;批量操作用 Fragment,追加 HTML 用 insertAdjacentHTML。下一章让页面响应用户:事件。