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

JavaScript学习教程,从入门到精通,DOM节点操作语法知识点及案例详解(21)

DOM节点操作语法知识点及案例详解

一、语法知识点

1. 获取节点

// 通过ID获取
const element = document.getElementById('idName');// 通过类名获取(返回HTMLCollection)
const elements = document.getElementsByClassName('className');// 通过标签名获取(返回HTMLCollection)
const tags = document.getElementsByTagName('div');// 通过CSS选择器获取单个元素
const el = document.querySelector('.selector');// 通过CSS选择器获取所有匹配元素(返回NodeList)
const nodes = document.querySelectorAll('div.item');// 特殊节点获取
document.documentElement;    // 获取html元素
document.head;               // 获取head元素
document.body;               // 获取body元素

2. 创建节点

// 创建元素节点
const newDiv = document.createElement('div');// 创建文本节点
const textNode = document.createTextNode('Hello World');// 创建文档片段(优化批量操作)
const fragment = document.createDocumentFragment();

3. 添加节点

// 末尾追加
parentNode.appendChild(childNode);// 指定位置插入
parentNode.insertBefore(newNode, referenceNode);// 插入HTML字符串(更灵活)
parentNode.insertAdjacentHTML('beforeend', '<div>New item</div>');
/*
位置参数:
'beforebegin':元素自身的前面
'afterbegin':插入元素内部的第一个子节点之前
'beforeend':插入元素内部的最后一个子节点之后
'afterend':元素自身的后面
*/

4. 删除节点

// 传统方法(需要父节点)
parentNode.removeChild(childNode);// 现代方法(直接操作)
childNode.remove();// 清空所有子节点
while (container.firstChild) {container.removeChild(container.firstChild);
}

5. 克隆节点

const cloneNode = originalNode.cloneNode(true); // true表示深度克隆

6. 节点关系

node.parentNode;        // 父节点
node.childNodes;        // 子节点集合
node.firstChild;        // 第一个子节点
node.lastChild;         // 最后一个子节点
node.previousSibling;   // 前一个兄弟节点
node.nextSibling;       // 后一个兄弟节点

二、综合案例

案例1:线上点菜系统

<!-- HTML结构 -->
<div class="container"><div class="menu"><h3>菜单列表</h3><ul id="foodList"><li>鱼香肉丝 <span class="price">¥28</span></li><li>宫保鸡丁 <span class="price">¥32</span></li><li>麻婆豆腐 <span class="price">¥18</span></li></ul></div><div class="ordered"><h3>已点菜品 <span id="total">总计:¥0</span></h3><ul id="orderedList"></ul></div>
</div><script>
// 初始化总价
let totalPrice = 0;// 菜单点击事件委托
document.getElementById('foodList').addEventListener('click', function(e) {if (e.target.tagName === 'LI') {// 克隆选中的菜品const clonedItem = e.target.cloneNode(true);// 添加删除按钮const delBtn = document.createElement('button');delBtn.textContent = '×';delBtn.className = 'delete-btn';clonedItem.appendChild(delBtn);// 添加到已点列表document.getElementById('orderedList').appendChild(clonedItem);// 更新总价const price = parseFloat(e.target.querySelector('.price').textContent.slice(1));totalPrice += price;updateTotal();}
});// 删除功能委托
document.getElementById('orderedList').addEventListener('click', function(e) {if (e.target.classList.contains('delete-btn')) {const listItem = e.target.parentElement;const price = parseFloat(listItem.querySelector('.price').textContent.slice(1));// 移除元素并更新总价listItem.remove();totalPrice -= price;updateTotal();}
});function updateTotal() {document.getElementById('total').textContent = `总计:¥${totalPrice.toFixed(2)}`;
}
</script>

案例2:电商购物车

<!-- HTML结构 -->
<div class="cart"><h2>购物车 <span id="cartTotal">¥0.00</span></h2><ul id="cartList"></ul><button id="addItem">添加商品</button>
</div><script>
class ShoppingCart {constructor() {this.items = [];this.cart = document.getElementById('cartList');this.init();}init() {// 添加示例商品this.addItem('iPhone 15', 7999);this.addItem('AirPods Pro', 1499);// 事件委托处理所有操作this.cart.addEventListener('click', (e) => {const itemEl = e.target.closest('.cart-item');if (!itemEl) return;const id = itemEl.dataset.id;const item = this.items.find(i => i.id == id);if (e.target.classList.contains('quantity-up')) {item.quantity++;} else if (e.target.classList.contains('quantity-down')) {if (item.quantity > 1) item.quantity--;} else if (e.target.classList.contains('delete-btn')) {this.removeItem(id);}this.updateItem(itemEl, item);this.updateTotal();});document.getElementById('addItem').addEventListener('click', () => {const name = prompt('请输入商品名称:');const price = parseFloat(prompt('请输入商品价格:'));if (name && price) this.addItem(name, price);});}addItem(name, price) {const newItem = {id: Date.now(),name,price,quantity: 1};this.items.push(newItem);this.renderItem(newItem);this.updateTotal();}renderItem(item) {const li = document.createElement('li');li.className = 'cart-item';li.dataset.id = item.id;li.innerHTML = `<span class="name">${item.name}</span><div class="controls"><button class="quantity-down">-</button><span class="quantity">${item.quantity}</span><button class="quantity-up">+</button></div><span class="price">¥${(item.price * item.quantity).toFixed(2)}</span><button class="delete-btn">删除</button>`;this.cart.appendChild(li);}updateItem(el, item) {el.querySelector('.quantity').textContent = item.quantity;el.querySelector('.price').textContent = `¥${(item.price * item.quantity).toFixed(2)}`;}removeItem(id) {this.items = this.items.filter(item => item.id != id);document.querySelector(`[data-id="${id}"]`).remove();}updateTotal() {const total = this.items.reduce((sum, item) => sum + item.price * item.quantity, 0);document.getElementById('cartTotal').textContent = `¥${total.toFixed(2)}`;}
}// 初始化购物车
new ShoppingCart();
</script>

三、关键知识点解析

  1. 事件委托:两个案例都使用了事件委托处理动态元素的事件,通过检查event.target来识别操作源

  2. 数据驱动:购物车案例将数据与DOM分离,保持数据源(this.items)与视图同步

  3. 克隆节点:点菜案例使用cloneNode(true)复制完整DOM结构

  4. 元素定位

    • closest() 方法查找最近的匹配祖先元素
    • dataset 属性操作自定义数据属性
  5. 数值处理

    • 使用toFixed(2)保持货币格式
    • 使用parseFloat处理价格转换
  6. 批量操作优化

    • 文档片段(document.createDocumentFragment)
    • 减少DOM操作次数(先计算后更新)

这些案例涵盖了DOM操作的核心知识点,实际开发中可结合CSS实现样式优化,并考虑添加本地存储功能实现数据持久化。

相关文章:

  • Android学习总结之APK打包流程
  • 使用Ingress发布应用程序
  • swift-12-Error处理、关联类型、assert、泛型_
  • ospf实验
  • 【HDFS入门】HDFS性能调优实战:压缩与编码技术深度解析
  • JavaScript中的Event事件对象详解
  • STL之vector基本操作
  • c语言中的原,反,补码
  • `Accelerate`库实现模型并行计算
  • STM32单片机入门学习——第42节: [12-2] BKP备份寄存器RTC实时时钟
  • QML动画--ParallelAnimation和SequentialAnimation
  • linux查看目录相关命令
  • SpringBoot启动后初始化的几种方式
  • 《关于加快推进虚拟电厂发展的指导意见》解读
  • Windows进程管理
  • 微信、抖音、小红书emoji符号大全
  • 【工具变量】A股上市公司信息披露质量KV指数测算数据集(含do代码 1991-2024年)
  • 多线程使用——线程安全、线程同步
  • -SSRF 服务端请求Gopher 伪协议无回显利用黑白盒挖掘业务功能点
  • Scade 语言词法介绍
  • 牛市早报|国常会:要持续稳定股市,4月LPR今日公布
  • 张九思任电子科大副教授,曾以学生身份入选爱思唯尔全球前2%顶尖科学家
  • 多元布局、抱团取暖……上海这个区和外向型企业坐到一起聊了什么
  • C909飞机开启越南商业运营
  • 擘画开放新篇 共筑合作之桥——中国银行上海市分行全力护航第八届进博会筹备工作
  • 郑州一废弃饭店堆砌物起火:明火被扑灭,未造成人员伤亡