切换主题
浏览器环境,规格
浏览器环境提供了 JavaScript 运行所需的所有功能,包括:
- 核心 JavaScript 语言:ECMAScript 规范定义的语言特性
- DOM(文档对象模型):用于操作 HTML 和 XML 文档
- BOM(浏览器对象模型):用于操作浏览器窗口和导航
- Web API:如 WebSocket、Web Storage、Web Workers 等
浏览器环境的主要对象
javascript
// 全局对象
window // 浏览器窗口对象
document // 文档对象
navigator // 浏览器信息对象
location // URL 对象
history // 历史记录对象
screen // 屏幕对象
DOM 树
DOM 树是 HTML 文档的树形结构表示,每个 HTML 元素都是一个节点:
- 文档节点:整个文档的根节点
- 元素节点:HTML 标签
- 文本节点:文本内容
- 属性节点:HTML 属性
- 注释节点:HTML 注释
DOM 树示例
html
<!DOCTYPE html>
<html>
<head>
<title>示例</title>
</head>
<body>
<div class="container">
<h1>标题</h1>
<p>段落文本</p>
</div>
</body>
</html>
对应的 DOM 树结构:
Document
└── html
├── head
│ └── title
│ └── "示例"
└── body
└── div.container
├── h1
│ └── "标题"
└── p
└── "段落文本"
遍历 DOM
1. 节点类型
javascript
// 节点类型常量
Node.ELEMENT_NODE // 1
Node.TEXT_NODE // 3
Node.COMMENT_NODE // 8
Node.DOCUMENT_NODE // 9
// 检查节点类型
element.nodeType === Node.ELEMENT_NODE
2. 节点属性
javascript
// 获取节点名称
element.nodeName // 元素标签名
element.nodeValue // 文本节点的内容
// 获取节点类型
element.nodeType // 节点类型数字
3. 遍历方法
javascript
// 遍历子节点
function traverseChildren(node) {
let child = node.firstChild;
while (child) {
console.log(child.nodeName);
child = child.nextSibling;
}
}
// 遍历所有后代节点
function traverseDescendants(node) {
let current = node.firstChild;
while (current) {
console.log(current.nodeName);
if (current.firstChild) {
traverseDescendants(current);
}
current = current.nextSibling;
}
}
// 使用 TreeWalker 遍历
const walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_ELEMENT,
null,
false
);
let node;
while (node = walker.nextNode()) {
console.log(node.nodeName);
}
4. 节点集合
javascript
// 获取所有子节点
const children = element.childNodes;
// 获取所有元素子节点
const elements = element.children;
// 获取第一个子节点
const firstChild = element.firstChild;
// 获取最后一个子节点
const lastChild = element.lastChild;
// 获取父节点
const parent = element.parentNode;
// 获取下一个兄弟节点
const nextSibling = element.nextSibling;
// 获取上一个兄弟节点
const previousSibling = element.previousSibling;
5. 节点操作
javascript
// 添加子节点
parent.appendChild(child);
// 在指定节点前插入
parent.insertBefore(newNode, referenceNode);
// 替换节点
parent.replaceChild(newNode, oldNode);
// 删除节点
parent.removeChild(child);
// 克隆节点
const clone = node.cloneNode(true); // true 表示深度克隆
Document 对象
Document 对象是 Web 页面的根节点,提供了对页面所有 HTML 元素的访问。
基本概念
Document 对象是 Window 对象的一部分,可通过 window.document
或 document
直接访问。
javascript
console.log(document === window.document); // true
常用属性
1. 文档元数据
javascript
// 获取文档标题
console.log(document.title);
// 设置文档标题
document.title = '新标题';
// 获取当前 URL
console.log(document.URL);
// 获取域名
console.log(document.domain);
// 获取最后修改日期
console.log(document.lastModified);
2. 文档状态
javascript
// 检查文档是否准备完毕
console.log(document.readyState); // 'loading', 'interactive' 或 'complete'
// DOM 内容加载完成事件
document.addEventListener('DOMContentLoaded', () => {
console.log('DOM 已加载完成');
});
选择元素
1. 通过 ID 选择
javascript
const element = document.getElementById('myId');
2. 通过类名选择
javascript
const elements = document.getElementsByClassName('myClass');
3. 通过标签名选择
javascript
const elements = document.getElementsByTagName('div');
4. 通过 CSS 选择器选择
javascript
// 选择第一个匹配的元素
const element = document.querySelector('.myClass');
// 选择所有匹配的元素
const elements = document.querySelectorAll('div.item');
创建和修改元素
1. 创建元素
javascript
// 创建新元素
const div = document.createElement('div');
div.className = 'container';
div.textContent = '这是一个新元素';
// 添加到文档
document.body.appendChild(div);
2. 插入 HTML
javascript
// 使用 innerHTML
element.innerHTML = '<span>新内容</span>';
// 使用 insertAdjacentHTML
element.insertAdjacentHTML('beforeend', '<span>新内容</span>');
3. 删除元素
javascript
// 删除子元素
parent.removeChild(child);
// 元素自删除
element.remove();
操作属性
1. 获取和设置属性
javascript
// 获取属性
const value = element.getAttribute('data-id');
// 设置属性
element.setAttribute('data-id', '123');
// 删除属性
element.removeAttribute('data-id');
2. 数据属性
javascript
// 使用 dataset 访问 data-* 属性
element.dataset.id = '123';
console.log(element.dataset.id); // '123'
DOM 遍历
1. 父子关系
javascript
// 获取父元素
const parent = element.parentNode;
// 获取子元素
const children = element.children;
const firstChild = element.firstElementChild;
const lastChild = element.lastElementChild;
2. 兄弟关系
javascript
// 获取前一个兄弟元素
const prev = element.previousElementSibling;
// 获取后一个兄弟元素
const next = element.nextElementSibling;
操作样式
1. 内联样式
javascript
// 设置内联样式
element.style.color = 'red';
element.style.fontSize = '16px';
// 获取内联样式
console.log(element.style.color);
2. 计算样式
javascript
// 获取计算后的样式
const style = window.getComputedStyle(element);
console.log(style.color);
3. 类操作
javascript
// 添加类
element.classList.add('active');
// 删除类
element.classList.remove('active');
// 切换类
element.classList.toggle('active');
// 检查是否包含类
console.log(element.classList.contains('active'));
事件管理
javascript
// 添加事件监听器
document.addEventListener('click', function(event) {
console.log('点击了文档');
});
// 移除事件监听器
document.removeEventListener('click', handler);
文档片段
javascript
// 创建文档片段(提高性能)
const fragment = document.createDocumentFragment();
// 添加多个元素到片段
for (let i = 0; i < 10; i++) {
const div = document.createElement('div');
div.textContent = `项目 ${i}`;
fragment.appendChild(div);
}
// 一次性添加到 DOM
document.body.appendChild(fragment);
表单操作
javascript
// 获取表单
const form = document.forms[0]; // 或 document.forms['myForm']
// 获取表单元素
const input = form.elements['username'];
// 表单提交
form.addEventListener('submit', function(event) {
event.preventDefault(); // 阻止默认提交
console.log('表单提交');
});
性能优化
1. 避免频繁 DOM 操作
javascript
// 不好的做法
for (let i = 0; i < 1000; i++) {
document.body.innerHTML += `<div>${i}</div>`;
}
// 好的做法
let html = '';
for (let i = 0; i < 1000; i++) {
html += `<div>${i}</div>`;
}
document.body.innerHTML = html;
2. 使用事件委托
javascript
// 不好的做法:为每个按钮添加事件
const buttons = document.querySelectorAll('button');
buttons.forEach(button => {
button.addEventListener('click', handleClick);
});
// 好的做法:使用事件委托
document.addEventListener('click', function(event) {
if (event.target.tagName === 'BUTTON') {
handleClick(event);
}
});
安全考虑
1. 防止 XSS 攻击
javascript
// 不安全的做法
element.innerHTML = userInput;
// 安全的做法
element.textContent = userInput;
2. 安全地插入 HTML
javascript
// 使用 DOMPurify 库清理 HTML
const clean = DOMPurify.sanitize(userInput);
element.innerHTML = clean;
最佳实践
- 尽量减少 DOM 操作,避免重绘和重排
- 使用事件委托处理多元素事件
- 使用文档片段进行批量操作
- 缓存频繁使用的 DOM 引用
- 使用 querySelector 而非较旧的 DOM 选择方法
- 小心处理用户输入,防止 XSS 攻击
- 利用 dataset 属性存储数据,避免自定义属性