JavaScript 中的 Document 对象详解
一、Document 对象概述
1. 定义与作用
Document 对象是浏览器中 HTML 文档的入口点,是 Window 对象的属性(即 window.document)。它代表整个 HTML 页面,提供了操作和访问页面内容的方法和属性,是 DOM(文档对象模型)的核心。
2. 核心功能
访问和修改 HTML 元素
处理事件
动态创建和修改页面内容
操作 CSS 样式
与浏览器历史记录交互
处理 cookies
3. 文档类型
Document 对象可以表示不同类型的文档:
HTML 文档(HTMLDocument)
XML 文档(XMLDocument)
SVG 文档(SVGDocument)
二、Document 对象的基本属性
1. 文档元信息
URL 相关
console.log(document.URL); // 当前文档的完整 URL
console.log(document.domain); // 当前文档的域名
console.log(document.baseURI); // 文档的基础 URI
标题和字符编码
document.title = '新标题'; // 获取或设置文档标题
document.charset = 'UTF-8'; // 获取或设置字符编码
引用和最后修改时间
console.log(document.referrer); // 链接到当前页面的前一个页面的 URL
console.log(document.lastModified); // 文档的最后修改时间
2. 文档结构引用
根元素
const htmlElement = document.documentElement; // <html> 元素
body 和 head
const body = document.body; // <body> 元素
const head = document.head; // <head> 元素
文档模式
console.log(document.compatMode); // 文档渲染模式 (CSS1Compat 或 BackCompat)
3. 文档状态
console.log(document.readyState); // 文档加载状态: loading, interactive, complete
// 监听文档加载完成
document.addEventListener('DOMContentLoaded', () => {
console.log('DOM 加载完成');
});
window.addEventListener('load', () => {
console.log('页面完全加载完成');
});
三、选择和查找元素
1. 通过 ID 选择
const element = document.getElementById('myId'); // 返回单个元素
2. 通过标签名选择
const elements = document.getElementsByTagName('p'); // 返回 HTMLCollection
3. 通过类名选择
const elements = document.getElementsByClassName('myClass'); // 返回 HTMLCollection
4. 通过选择器选择
querySelector
const element = document.querySelector('div.container'); // 返回第一个匹配的元素
querySelectorAll
const elements = document.querySelectorAll('p.highlight'); // 返回 NodeList
5. 元素集合差异
HTMLCollection
动态集合,元素变化时自动更新
只能通过索引访问
示例:getElementsByTagName() 的返回值
NodeList
静态集合或动态集合(取决于创建方式)
可以通过索引和 forEach 访问
示例:querySelectorAll() 的返回值
四、创建和修改元素
1. 创建元素
const newDiv = document.createElement('div');
newDiv.className = 'container';
newDiv.textContent = '新创建的元素';
2. 添加元素
appendChild
document.body.appendChild(newDiv);
insertBefore
const referenceNode = document.getElementById('reference');
document.body.insertBefore(newDiv, referenceNode);
3. 删除元素
const elementToRemove = document.getElementById('toRemove');
elementToRemove.parentNode.removeChild(elementToRemove);
// 现代方法
elementToRemove.remove();
4. 替换元素
const newElement = document.createElement('span');
const oldElement = document.getElementById('old');
oldElement.parentNode.replaceChild(newElement, oldElement);
5. 复制元素
const clone = newDiv.cloneNode(true); // true 表示深复制,包含所有子节点
document.body.appendChild(clone);
五、处理 HTML 和文本内容
1. innerHTML
// 获取内容
const content = element.innerHTML;
// 设置内容
element.innerHTML = '<p>新内容</p>';
2. outerHTML
// 获取元素及其内容的 HTML
const html = element.outerHTML;
// 替换整个元素
element.outerHTML = '<div class="new">新元素</div>';
3. textContent
// 获取纯文本内容
const text = element.textContent;
// 设置纯文本内容
element.textContent = '这是纯文本';
4. innerText
// 获取可见文本内容(考虑 CSS 样式)
const visibleText = element.innerText;
六、操作属性
1. 获取属性
const href = link.getAttribute('href');
2. 设置属性
link.setAttribute('href', 'https://example.com');
link.setAttribute('target', '_blank');
3. 检查属性
const hasAttr = link.hasAttribute('href');
4. 删除属性
link.removeAttribute('target');
5. 直接属性访问
// 标准属性可以直接访问
link.href = 'https://example.com';
input.value = '新值';
img.src = 'new-image.jpg';
// 自定义属性使用 dataset
element.dataset.userId = '123'; // 对应 HTML 中的 data-user-id
七、样式操作
1. 内联样式
element.style.color = 'red';
element.style.backgroundColor = 'yellow';
element.style.fontSize = '16px';
2. 类操作
// 添加类
element.classList.add('active');
// 移除类
element.classList.remove('hidden');
// 切换类
element.classList.toggle('highlight');
// 检查类
const hasClass = element.classList.contains('active');
3. 计算样式
const computedStyle = window.getComputedStyle(element);
console.log(computedStyle.color);
console.log(computedStyle.width);
八、事件处理
1. 事件监听
const button = document.getElementById('myButton');
// 添加事件监听器
button.addEventListener('click', (event) => {
console.log('按钮被点击');
console.log('事件对象:', event);
});
// 移除事件监听器(需要使用相同的函数引用)
const handleClick = () => {
console.log('另一个点击处理函数');
};
button.addEventListener('click', handleClick);
button.removeEventListener('click', handleClick);
2. 常见事件类型
鼠标事件:click, dblclick, mouseover, mouseout, mousemove
键盘事件:keydown, keyup, keypress
表单事件:submit, change, focus, blur
窗口事件:load, resize, scroll, unload
DOM 事件:DOMContentLoaded
3. 事件委托
document.getElementById('parent').addEventListener('click', (event) => {
if (event.target.classList.contains('child')) {
console.log('子元素被点击');
}
});
九、文档加载与状态
1. 加载事件
DOMContentLoaded
document.addEventListener('DOMContentLoaded', () => {
// DOM 已加载完成,但可能尚未加载所有资源
console.log('DOM 加载完成');
});
load
window.addEventListener('load', () => {
// 页面所有资源(包括图片、脚本等)已加载完成
console.log('页面完全加载完成');
});
2. 文档状态检查
if (document.readyState === 'complete') {
// 文档已完全加载
} else {
document.addEventListener('DOMContentLoaded', () => {
// 文档加载完成后执行
});
}
十、特殊文档操作
1. 创建文档片段
const fragment = document.createDocumentFragment();
const li1 = document.createElement('li');
li1.textContent = '项目 1';
const li2 = document.createElement('li');
li2.textContent = '项目 2';
fragment.appendChild(li1);
fragment.appendChild(li2);
document.getElementById('myList').appendChild(fragment);
2. 创建文本节点
const textNode = document.createTextNode('这是一个文本节点');
element.appendChild(textNode);
3. 创建注释节点
const comment = document.createComment('这是一个注释');
element.appendChild(comment);
4. 处理表单
const form = document.getElementById('myForm');
// 获取表单数据
const formData = new FormData(form);
for (const [key, value] of formData) {
console.log(key, value);
}
// 提交表单
form.submit();
十一、Document 对象的高级用法
1. 操作 cookie
// 设置 cookie
document.cookie = 'username=John; expires=Thu, 31 Dec 2025 23:59:59 GMT; path=/';
// 获取 cookie
const cookies = document.cookie.split('; ');
const username = cookies.find(c => c.startsWith('username='))?.split('=')[1];
console.log('用户名:', username);
2. 打印文档
window.print();
3. 文档模式
console.log(document.compatMode); // CSS1Compat 或 BackCompat
4. 查找和选择文本
// 选中文本
const selection = window.getSelection();
const range = document.createRange();
range.selectNodeContents(document.getElementById('myText'));
selection.removeAllRanges();
selection.addRange(range);
5. 执行脚本
const script = document.createElement('script');
script.src = 'https://example.com/script.js';
document.head.appendChild(script);
十二、性能优化
1. 批量 DOM 操作
// 低效
for (let i = 0; i < 1000; i++) {
document.body.appendChild(document.createElement('div'));
}
// 高效
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
fragment.appendChild(document.createElement('div'));
}
document.body.appendChild(fragment);
2. 缓存 DOM 引用
// 低效
for (let i = 0; i < 1000; i++) {
document.getElementById('myElement').style.left = i + 'px';
}
// 高效
const element = document.getElementById('myElement');
for (let i = 0; i < 1000; i++) {
element.style.left = i + 'px';
}
3. 使用事件委托
// 为大量按钮添加事件
document.getElementById('container').addEventListener('click', (event) => {
if (event.target.tagName === 'BUTTON') {
console.log('按钮被点击');
}
});
十三、安全注意事项
1. XSS 防护
// 不安全
const userInput = '<script>alert("XSS");</script>';
document.getElementById('output').innerHTML = userInput;
// 安全
const textNode = document.createTextNode(userInput);
document.getElementById('output').appendChild(textNode);
2. 安全的 innerHTML 使用
function safeSetHTML(element, html) {
const temp = document.createElement('div');
temp.innerHTML = html;
// 过滤危险元素
const scripts = temp.querySelectorAll('script');
scripts.forEach(script => script.remove());
element.innerHTML = temp.innerHTML;
}
十四、兼容性考虑
1. 旧浏览器支持
使用 document.querySelector 和 document.querySelectorAll 替代 getElementById 等方法时,需注意 IE8+ 支持。
使用 classList 时需注意 IE10+ 支持。
2. 特性检测
if ('querySelector' in document) {
// 使用 querySelector
} else {
// 使用 getElementById 等替代方法
}
十五、Document 对象与现代框架
1. 与 React 的关系
React 使用虚拟 DOM 减少直接操作 Document 对象。
通过 ref 可以访问真实 DOM 元素。
2. 与 Vue 的关系
Vue 通过指令和组件操作 DOM,减少直接操作 Document 对象。
通过 ref 可以访问真实 DOM 元素。
Document 对象是 JavaScript 与 HTML 页面交互的核心,掌握其用法对于开发高性能、交互性强的 Web 应用至关重要。通过合理使用 Document 对象的各种方法和属性,可以实现从简单的元素选择到复杂的动态页面构建的各种功能。


















暂无评论内容