Appearance
DOM/BOM 操作、表单处理与事件模型
本文梳理 BOM (浏览器对象模型) 核心 API、DOM 节点检索与动态渲染、事件冒泡与捕获机制、事件委托性能优化以及正则表达式表单验证。
1. BOM (Browser Object Model) 核心对象
BOM 提供了独立于网页内容、与浏览器窗口进行交互的对象结构:
window:BOM 的顶层全局对象,代表浏览器窗口。location:用于获取或设置当前页面的地址栏 URL。location.href:获取或重定向页面地址(如location.href = 'login.html')。location.search:获取查询参数部分(即?及之后的部分)。location.reload():重新加载当前页面。
history:管理浏览器的历史记录(history.back(),history.forward(),history.go(-1))。navigator:提供浏览器内核与环境信息(如通过navigator.userAgent判定浏览器或移动终端设备)。
2. DOM 节点操作与动态渲染
DOM (Document Object Model) 将 HTML 文档解析为一个层级化的节点树结构:
2.1 节点检索与选择器
javascript
// 现代标准推荐 API
const element = document.querySelector('#submit-btn'); // 单个元素
const listItems = document.querySelectorAll('.menu-item'); // NodeList 集合2.2 节点的增删改查
javascript
// 1. 创建新节点
const newLi = document.createElement('li');
newLi.className = 'list-item';
newLi.textContent = '新节点项';
// 2. 挂载到父节点
const ul = document.querySelector('#my-list');
ul.appendChild(newLi);
// 3. 删除与替换节点
// ul.removeChild(newLi);
// ul.replaceChild(newElement, oldElement);3. 事件处理模型与事件委托
3.1 事件流 3 阶段
当页面元素接收到事件时,事件会在 DOM 树结构中按如下顺序传播:
1. 捕获阶段 (Capture Phase) ──(Window -> Document -> Body -> 目标父元素)──>
2. 目标阶段 (Target Phase) ──(到达真正的事件触发元素)──>
3. 冒泡阶段 (Bubble Phase) ──(从目标元素冒泡回 Window)通过 addEventListener 的第 3 个参数可控制监听捕获或冒泡:
javascript
// addEventListener(type, listener, useCapture)
// useCapture 为 false (默认):在冒泡阶段触发;为 true:在捕获阶段触发
element.addEventListener('click', (event) => {
event.preventDefault(); // 阻止默认行为(如阻止 a 标签跳转或 form 提交)
event.stopPropagation(); // 阻止事件进一步向上冒泡
}, false);3.2 事件委托 (Event Delegation)
利用事件冒泡原理,将多个子元素的事件监听统一绑定在它们的公共父元素上。
- 优势:极大减少事件处理函数的数量与内存开销;对未来动态新增的子节点天然有效。
javascript
// 为父元素绑定单击监听
const container = document.querySelector('#card-container');
container.addEventListener('click', (event) => {
// 通过 event.target 判断真正被点击的子元素
if (event.target && event.target.matches('.delete-btn')) {
console.log('点击了删除按钮,卡片ID:', event.target.dataset.id);
}
});4. 正则表达式 (RegExp) 与表单验证
正则表达式用以匹配与校验文本格式(如邮箱、手机号):
javascript
// 手机号正则表达式校验规范(中国大陆 11 位手机号)
const phoneReg = /^1[3-9]\d{9}$/;
const inputPhone = '13812345678';
if (phoneReg.test(inputPhone)) {
console.log('手机号格式正确');
} else {
console.log('手机号格式不合法');
}