当前位置: 首页 > news >正文

通俗易懂的 JS DOM 操作指南:从创建到挂载

目录

🧩 1. 创建元素:document.createElement / createElementNS

📝 2. 创建文本:document.createTextNode

✏️ 3. 修改文本:node.nodeValue

🗑️ 4. 移除元素:el.removeChild()

📍 5. 精准插入:el.insertBefore()

➕ 6. 尾部追加:el.appendChild()

👨‍👦 7. 获取父元素:el.parentNode

👉 8. 获取兄弟元素:el.nextSibling

🌀 9. 挂载 Portal:document.querySelector

🌰 综合应用示例:动态列表操作

📚 核心知识点总结

DOM 演示操作 文档


理解 DOM 操作是前端开发的核心基础。下面我会用通俗的语言和实际场景,带你掌握这些关键 API 的使用技巧:

🧩 1. 创建元素:document.createElement / createElementNS

作用:创建 HTML 元素(标签)

区别

createElement:创建普通 HTML 元素

const div = document.createElement('div'); // 创建 <div>
const button = document.createElement('button'); // 创建 <button>

createElementNS:创建带命名空间的元素(如 SVG)

// 创建 SVG 元素必须使用命名空间
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');

📝 2. 创建文本:document.createTextNode

  • 作用:创建纯文本节点(非 HTML)

  • 场景:当需要插入纯文本时(避免 XSS 攻击)

const text = document.createTextNode('安全文本内容');
div.appendChild(text); // <div>安全文本内容</div>

✏️ 3. 修改文本:node.nodeValue

  • 作用:修改文本节点的内容(注意:不适用于元素节点!)

  • 正确用法

const textNode = document.createTextNode('原始文本');
div.appendChild(textNode);// 修改文本内容
textNode.nodeValue = '修改后的文本'; // div内容实时更新

🗑️ 4. 移除元素:el.removeChild()

  • 作用:从父元素中移除指定的子元素

  • 三步操作

const parent = document.getElementById('parent');
const child = document.getElementById('child');// 必须通过父元素执行移除
parent.removeChild(child);

📍 5. 精准插入:el.insertBefore()

  • 作用:在指定子节点插入新元素

  • 参数顺序父元素.insertBefore(新元素, 参考元素)

const list = document.getElementById('list');
const newItem = document.createElement('li');
const thirdItem = list.children[2];// 在第三个元素前插入
list.insertBefore(newItem, thirdItem);

➕ 6. 尾部追加:el.appendChild()

  • 作用:在父元素末尾添加子元素

  • 最常用操作

const container = document.querySelector('.container');
const newCard = document.createElement('div');container.appendChild(newCard); // 添加到container末尾

👨‍👦 7. 获取父元素:el.parentNode

  • 作用:获取当前元素的直接父元素

  • 典型场景:事件委托

button.addEventListener('click', (e) => {// 点击按钮后获取其父元素const parent = e.target.parentNode;parent.style.backgroundColor = 'yellow';
});
;

👉 8. 获取兄弟元素:el.nextSibling

  • 注意:返回下一个节点(可能是文本/注释/元素)

  • 实际使用:通常配合 nodeType 过滤

const current = document.getElementById('item3');
let next = current.nextSibling;// 跳过文本节点(如换行符)
while (next && next.nodeType !== 1) {next = next.nextSibling;
}
console.log(next); // 得到下一个元素节点

🌀 9. 挂载 Portal:document.querySelector

  • 特殊场景:渲染到 DOM 树之外的位置(如模态框)

// 在 body 末尾创建模态框容器
const modalRoot = document.createElement('div');
document.body.appendChild(modalRoot);// 创建 Portal 内容
const modalContent = document.createElement('div');
modalContent.innerHTML = '<h2>登录窗口</h2>';// 挂载到指定容器
const container = document.querySelector('#portal-root');
container.appendChild(modalContent);

🌰 综合应用示例:动态列表操作

<ul id="list"><li>第一项</li><li>第二项</li>
</ul>
<button id="btn">添加项目</button><script>const list = document.getElementById('list');const btn = document.getElementById('btn');btn.addEventListener('click', () => {// 1. 创建元素const newItem = document.createElement('li');// 2. 创建文本(安全方式)const text = document.createTextNode('新项目');newItem.appendChild(text);// 3. 在第二项前插入const secondItem = list.querySelector('li:nth-child(2)');list.insertBefore(newItem, secondItem);// 4. 添加删除功能newItem.onclick = function() {this.parentNode.removeChild(this); // 通过父元素移除};});
</script>

📚 核心知识点总结

API作用注意事项
createElement创建 HTML 元素区分普通元素和 SVG
createTextNode创建安全文本节点防止 XSS 攻击
nodeValue修改文本节点内容对元素节点无效
removeChild父元素移除子元素需通过父元素调用
insertBefore在指定位置插入元素参数顺序:(新元素, 参考元素)
appendChild末尾添加元素最常用的添加方法
parentNode获取父元素事件委托的关键
nextSibling获取下一个兄弟节点可能包含文本节点
querySelector精确查找元素Portal 挂载的核心

💡 最佳实践提示:操作 DOM 时,尽量减少重排(reflow)次数。可通过创建文档片段(DocumentFragment)批量操作元素后再一次性添加到 DOM 树中。

掌握这些基础 API 后,你将能轻松应对大多数 DOM 操作需求,为学习现代前端框架打下坚实基础!

DOM 演示操作 文档

<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>DOM操作演示</title><style>* {margin: 0;padding: 0;box-sizing: border-box;font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;}body {background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);color: #fff;min-height: 100vh;padding: 20px;line-height: 1.6;}.container {max-width: 1200px;margin: 0 auto;padding: 20px;}header {text-align: center;padding: 20px 0;margin-bottom: 30px;background: rgba(0, 0, 0, 0.3);border-radius: 15px;box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);backdrop-filter: blur(4px);border: 1px solid rgba(255, 255, 255, 0.1);}h1 {font-size: 2.8rem;margin-bottom: 10px;text-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);}.subtitle {font-size: 1.2rem;opacity: 0.9;max-width: 800px;margin: 0 auto;}.content {display: flex;flex-wrap: wrap;gap: 30px;margin-bottom: 40px;}.demo-section {flex: 1;min-width: 300px;background: rgba(0, 0, 0, 0.2);border-radius: 15px;padding: 25px;box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);backdrop-filter: blur(4px);border: 1px solid rgba(255, 255, 255, 0.1);}.section-title {font-size: 1.8rem;margin-bottom: 20px;color: #ffcc00;text-align: center;}.controls {display: flex;flex-wrap: wrap;gap: 15px;margin-bottom: 25px;}.btn {flex: 1;min-width: 200px;padding: 15px 20px;background: linear-gradient(to right, #3498db, #2980b9);color: white;border: none;border-radius: 50px;font-size: 1.1rem;font-weight: 600;cursor: pointer;transition: all 0.3s ease;box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);}.btn:hover {transform: translateY(-3px);box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);background: linear-gradient(to right, #3cb0fd, #3498db);}.btn:active {transform: translateY(1px);}.btn-remove {background: linear-gradient(to right, #e74c3c, #c0392b);}.btn-remove:hover {background: linear-gradient(to right, #ff6b6b, #e74c3c);}.btn-insert {background: linear-gradient(to right, #2ecc71, #27ae60);}.btn-insert:hover {background: linear-gradient(to right, #1dd1a1, #2ecc71);}.btn-info {background: linear-gradient(to right, #9b59b6, #8e44ad);}.btn-info:hover {background: linear-gradient(to right, #be2edd, #9b59b6);}.demo-area {background: rgba(255, 255, 255, 0.1);border-radius: 10px;padding: 20px;min-height: 150px;margin-top: 20px;border: 1px solid rgba(255, 255, 255, 0.1);}.code-section {background: rgba(0, 0, 0, 0.3);border-radius: 10px;padding: 20px;margin-top: 20px;font-family: 'Courier New', monospace;font-size: 0.95rem;overflow-x: auto;border: 1px solid rgba(255, 255, 255, 0.1);}.dom-tree {background: rgba(255, 255, 255, 0.05);border-radius: 10px;padding: 15px;margin-top: 15px;font-family: monospace;font-size: 0.9rem;white-space: pre;overflow-x: auto;}.explanation {background: rgba(255, 255, 255, 0.05);border-radius: 10px;padding: 20px;margin-top: 20px;border-left: 4px solid #3498db;}.explanation h3 {color: #3498db;margin-bottom: 10px;}.highlight {background: rgba(255, 215, 0, 0.2);padding: 2px 5px;border-radius: 4px;}.counter {text-align: center;font-size: 1.2rem;margin-top: 20px;padding: 10px;background: rgba(0, 0, 0, 0.3);border-radius: 10px;}.element {color: #ffcc00;}.text-node {color: #1abc9c;}footer {text-align: center;padding: 20px;margin-top: 30px;background: rgba(0, 0, 0, 0.3);border-radius: 15px;}@media (max-width: 768px) {.content {flex-direction: column;}.btn {min-width: 100%;}}</style>
</head><body><div class="container"><header><h1>DOM 操作演示</h1><p class="subtitle">本演示展示了JavaScript中常用的DOM操作方法,包括创建元素、修改文本、插入节点、移除节点等操作。</p></header><div class="content"><div class="demo-section"><h2 class="section-title">文本节点操作</h2><div class="controls"><button id="edit" class="btn">修改文字 (nodeValue)</button><button id="remove" class="btn btn-remove">移除文本节点 (removeChild)</button></div><div class="demo-area" id="text-demo"><div id="app"></div></div><div class="code-section"><pre><code>// 创建元素和文本节点
const heading = document.createElement('h1');
const textNode = document.createTextNode('hello world');// 添加文本节点到元素
heading.appendChild(textNode);// 添加元素到DOM
app.appendChild(heading);// 修改文本
editBtn.addEventListener('click', () => {textNode.nodeValue = 'hello vue';
});// 移除文本节点
removeBtn.addEventListener('click', () => {if (textNode.parentNode) {heading.removeChild(textNode);}
});</code></pre></div><div class="explanation"><h3>说明</h3><p><span class="highlight">nodeValue</span> 属性用于获取或设置文本节点的内容。</p><p><span class="highlight">removeChild()</span> 方法从DOM中移除指定的子节点。</p></div></div><div class="demo-section"><h2 class="section-title">节点插入操作</h2><div class="controls"><button id="insertBefore" class="btn btn-insert">insertBefore (在指定节点前插入)</button><button id="insertBefore2" class="btn btn-insert">insertBefore (在末尾插入)</button><button id="parentNode" class="btn btn-info">显示父节点和兄弟节点</button></div><div class="demo-area"><div id="parentDiv"><h1 id="childElement">childElement (原始节点)</h1></div></div><div class="dom-tree" id="domTree"><!-- DOM树结构将在这里显示 --></div><div class="code-section"><pre><code>// 在指定节点前插入
insertBeforeBtn.addEventListener('click', () => {const newNode = document.createElement("span");newNode.textContent = '新插入的span (之前)';newNode.className = 'new-node';const parentDiv = childElement.parentNode;parentDiv.insertBefore(newNode, childElement);
});// 在末尾插入(相当于appendChild)
insertBefore2Btn.addEventListener('click', () => {const newNode = document.createElement("span");newNode.textContent = '新插入的span (末尾)';newNode.className = 'new-node';const parentDiv = childElement.parentNode;parentDiv.insertBefore(newNode, null);
});// 显示节点关系
parentNodeBtn.addEventListener('click', () => {const parent = childElement.parentNode;const nextSibling = childElement.nextSibling;// 显示在DOM树区域
});</code></pre></div><div class="explanation"><h3>说明</h3><p><span class="highlight">insertBefore()</span> 方法在参考节点之前插入一个节点。</p><p>如果参考节点为 <span class="highlight">null</span>,则新节点将插入到子节点列表的末尾。</p><p><span class="highlight">parentNode</span> 属性返回指定节点的父节点。</p><p><span class="highlight">nextSibling</span> 属性返回指定节点之后紧跟的节点。</p></div></div></div><div class="counter">操作计数: <span id="operationCount">0</span></div><footer><p>DOM 操作演示 &copy; 2023 | 通过本演示理解核心DOM操作</p></footer></div><script>// 操作计数器let operationCount = 0;const operationCountElement = document.getElementById('operationCount');// 更新操作计数function updateCounter() {operationCount++;operationCountElement.textContent = operationCount;}// 第一部分:文本节点操作const app = document.getElementById('app');const heading = document.createElement('h1');heading.className = 'element';const textNode = document.createTextNode('hello world');heading.appendChild(textNode);app.appendChild(heading);// 添加按钮事件document.getElementById('edit').addEventListener('click', () => {textNode.nodeValue = '文本已修改: hello vue!';updateCounter();});document.getElementById('remove').addEventListener('click', () => {if (textNode.parentNode) {heading.removeChild(textNode);updateCounter();}});// 第二部分:节点插入操作const childElement = document.getElementById('childElement');document.getElementById('insertBefore').addEventListener('click', () => {const newNode = document.createElement("span");newNode.textContent = '新插入的span (在原始节点之前)';newNode.className = 'new-node';const parentDiv = childElement.parentNode;parentDiv.insertBefore(newNode, childElement);updateCounter();updateDomTree();});document.getElementById('insertBefore2').addEventListener('click', () => {const newNode = document.createElement("span");newNode.textContent = '新插入的span (在父元素末尾)';newNode.className = 'new-node';const parentDiv = childElement.parentNode;parentDiv.insertBefore(newNode, null);updateCounter();updateDomTree();});document.getElementById('parentNode').addEventListener('click', () => {const parent = childElement.parentNode;const nextSibling = childElement.nextSibling;alert(`父节点ID: ${parent.id}\n下一个兄弟节点: ${nextSibling ? nextSibling.nodeName : '无'}`);updateCounter();});// 更新DOM树显示function updateDomTree() {const parentDiv = document.getElementById('parentDiv');const domTreeElement = document.getElementById('domTree');// 简单的DOM树表示let tree = `#${parentDiv.id}\n`;tree += `├── ${parentDiv.firstChild.nodeName} (文本节点)\n`;for (let i = 0; i < parentDiv.childNodes.length; i++) {const node = parentDiv.childNodes[i];if (node.nodeType === Node.ELEMENT_NODE) {tree += `├── <${node.nodeName.toLowerCase()}>`;if (node.id) tree += ` #${node.id}`;if (node.className) tree += ` .${node.className}`;if (node.textContent) tree += ` - "${node.textContent}"`;tree += '\n';}}domTreeElement.textContent = tree;}// 初始化DOM树显示updateDomTree();// 添加一些初始样式const style = document.createElement('style');style.textContent = `.element { color: #ffcc00; }.text-node { color: #1abc9c; }.new-node { display: block; padding: 10px; margin: 10px 0; background: rgba(52, 152, 219, 0.2); border: 1px dashed #3498db;border-radius: 5px;}`;document.head.appendChild(style);</script>
</body></html>

相关文章:

  • uniapp uni-id 如果是正式项目,需自行实现发送邮件的相关功能
  • 【Java基础】Java基础语法到高级特性
  • WEBSTORM前端 —— 第3章:移动 Web —— 第5节:响应式网页
  • Python 训练营打卡 Day 41
  • 船舶二阶非线性响应方程的EKF与UKF参数辨识
  • 使用BERT/BiLSTM + CRF 模型进行NER进展记录~
  • PyTorch ——torchvision数据集使用
  • 缓存击穿、缓存雪崩、缓存穿透以及数据库缓存双写不一致问题
  • 落石石头检测数据集VOC+YOLO格式1185张1类别
  • 【MySQL】第13节|MySQL 中模糊查询的全面总结
  • Mixly1.0/2.0/3.0 (windows系统) 安装教程及使用常见问题解决
  • leetcode179_最大数
  • 从认识AI开始-----Transformer:大模型的核心架构
  • 湖北理元理律师事务所:企业债务优化的科学路径与人文关怀
  • LLaMA-Factory - 批量推理(inference)的脚本
  • 《关于有序推动绿电直连发展有关事项的通知》核心内容
  • DAY40 训练和测试
  • 基于FashionMnist数据集的自监督学习(生成式自监督学习VAE算法)
  • 数据结构测试模拟题(3)
  • 【java面试】redis篇
  • 网站建设单位/德兴网站seo
  • seo查询网站/草根站长工具
  • 网站建设赵玉敏/东莞seo建站哪家好
  • 网站标ico怎么做/谷歌外贸seo
  • 广东像一起做网店的网站/seo工作是什么意思
  • 临泉网站建设/数据统计网站