JavaScript 浏览器特有内置对象和方法
简介
本文档介绍 浏览器环境中特有的内置对象和方法。这些 API 由浏览器(如 Chrome 的 V8 引擎所在的运行时)提供,不属于 ECMAScript 标准,因此在 Node.js 中不可用。
参考文档:
js-builtins.md— V8/ECMAScript 标准内置对象(Math、Date、JSON、Map、Set、Symbol 等)js-runtime.md— 浏览器和 Node.js 运行时对比
window 对象
window 是浏览器的全局对象。所有全局变量和函数都是 window 的属性。
基本用法
console.log(window); // Window 对象
// 全局变量自动成为 window 的属性
var globalVar = 'hello';
console.log(window.globalVar); // "hello"
// 全局函数
window.alert('Hello!');
// 在全局作用域中,this 指向 window(非严格模式)
console.log(this === window); // true
弹窗函数
// alert — 提示框(只有"确定"按钮)
alert('操作成功!');
// confirm — 确认框(有"确定"和"取消")
let result = confirm('确定要删除吗?');
console.log(result); // 点击"确定"返回 true,否则 false
// prompt — 输入框(返回输入的字符串或 null)
let name = prompt('请输入姓名:', '默认名'); // 第二个参数是默认值
if (name !== null) {
console.log('你好,' + name);
}
注意:现代 Web 开发中不推荐使用这些弹窗,因为它们会阻塞线程且体验不佳,应使用自定义的模态框代替。
Document 对象(DOM)
document 是 window 的属性,表示当前网页的文档对象。
查找元素
// 通过 ID 查找(返回单个元素)
let title = document.getElementById('title');
console.log(title.textContent);
// 通过 CSS 选择器查找
let firstItem = document.querySelector('.item'); // 第一个匹配的元素
let allItems = document.querySelectorAll('.item'); // 所有匹配的元素(NodeList)
// 通过标签名、类名、名称查找
let divs = document.getElementsByTagName('div');
let items = document.getElementsByClassName('item');
let inputs = document.getElementsByName('username');
创建和插入元素
// 创建新元素
let div = document.createElement('div');
div.id = 'my-div';
div.className = 'container';
div.textContent = 'Hello World';
// 插入到页面
document.body.appendChild(div); // 追加为最后一个子元素
let parent = document.getElementById('container');
let referenceNode = document.getElementById('ref');
parent.insertBefore(div, referenceNode); // 插入到参考节点之前
// 现代方法(ES6+)
parent.prepend(div); // 插入到开头
parent.append(div); // 插入到末尾(可插入多个)
parent.before(div); // 插入到元素前
parent.after(div); // 插入到元素后
修改元素内容和属性
let elem = document.getElementById('my-element');
// 文本内容
elem.textContent = '新文本'; // 只设置/获取文本内容
elem.innerText = '新文本'; // 考虑样式的文本(不包含隐藏元素文本)
// HTML 内容(注意 XSS 风险)
elem.innerHTML = '<strong>加粗文本</strong>'; // 解析 HTML
elem.insertAdjacentHTML('beforeend', '<p>追加的内容</p>');
// 位置参数:beforebegin / afterbegin / beforeend / afterend
// 属性操作
elem.setAttribute('data-id', '123');
console.log(elem.getAttribute('data-id')); // "123"
elem.removeAttribute('data-id');
// className 和 classList
elem.className = 'btn btn-primary'; // 设置类名(覆盖)
elem.classList.add('active'); // 添加类
elem.classList.remove('active'); // 移除类
elem.classList.toggle('active'); // 切换类
console.log(elem.classList.contains('active')); // 是否包含类
// style 样式
elem.style.color = 'red';
elem.style.backgroundColor = 'blue';
elem.style.display = 'none';
删除元素
let elem = document.getElementById('to-remove');
elem.remove(); // 现代方法(ES6)
// 传统方法
if (elem.parentNode) {
elem.parentNode.removeChild(elem);
}
事件监听
let btn = document.getElementById('my-btn');
// addEventListener — 推荐方式(可添加多个监听)
btn.addEventListener('click', function(event) {
console.log('按钮被点击了!');
console.log(event.target); // 触发事件的元素
});
// 带选项的参数
btn.addEventListener('click', handler, {
capture: false, // 是否在捕获阶段(默认 false = 冒泡阶段)
once: true // 只执行一次
});
// 移除监听
function handler() { console.log('clicked'); }
btn.addEventListener('click', handler);
btn.removeEventListener('click', handler);
// 传统方式(不推荐,只能设置一个)
// btn.onclick = function() { console.log('clicked'); };
// btn.onclick = null; // 移除
// 事件对象常用属性
btn.addEventListener('click', (e) => {
e.preventDefault(); // 阻止默认行为(如链接跳转、表单提交)
e.stopPropagation(); // 阻止事件冒泡
console.log(e.type); // "click"(事件类型)
console.log(e.clientX, e.clientY); // 鼠标坐标
});
事件传播:冒泡和捕获
// 冒泡(默认):从内到外
// 捕获:从外到内(addEventListener 第三个参数设为 true)
<div id="outer">
<button id="inner">点击</button>
</div>
<script>
let outer = document.getElementById('outer');
let inner = document.getElementById('inner');
// 捕获阶段
outer.addEventListener('click', () => console.log('外层捕获'), true);
// 冒泡阶段(默认)
outer.addEventListener('click', () => console.log('外层冒泡'));
inner.addEventListener('click', () => console.log('内层冒泡'));
// 点击按钮输出顺序:
// 外层捕获 → 内层冒泡 → 外层冒泡
</script>
常用事件速查表
| 事件类型 | 说明 | 适用元素 |
|---|---|---|
click |
点击事件 | 大部分元素 |
dblclick |
双击事件 | 大部分元素 |
mousedown / mouseup |
鼠标按下/松开 | 大部分元素 |
mousemove |
鼠标移动 | 大部分元素 |
keydown / keyup |
键盘按下/松开 | 可聚焦元素 |
input |
输入内容变化 | input、textarea |
change |
值改变并提交 | input、select |
submit |
表单提交 | form |
load |
资源加载完成 | window、img 等 |
DOMContentLoaded |
DOM 解析完成 | document |
resize |
窗口大小变化 | window |
scroll |
滚动 | window、可滚动元素 |
focus / blur |
获取/失去焦点 | 可聚焦元素 |
BOM(浏览器对象模型)
BOM 提供了与浏览器窗口交互的 API。
navigator — 浏览器信息
console.log(navigator.userAgent); // 浏览器 UA 字符串
console.log(navigator.language); // 浏览器语言(如 "zh-CN")
console.log(navigator.languages); // 支持的语言列表
console.log(navigator.onLine); // 是否在线
console.log(navigator.platform); // 操作系统平台
// 检查是否在线
if (navigator.onLine) {
console.log('当前在线');
} else {
console.log('当前离线');
}
location — URL 信息
// location 对象包含当前 URL 的信息
console.log(location.href); // 完整 URL
console.log(location.protocol); // 协议(如 "https:")
console.log(location.host); // 主机名+端口(如 "example.com:8080")
console.log(location.hostname); // 主机名(如 "example.com")
console.log(location.port); // 端口(如 "8080")
console.log(location.pathname); // 路径(如 "/page/index.html")
console.log(location.search); // 查询字符串(如 "?id=1&sort=name")
console.log(location.hash); // 哈希(如 "#section1")
// 跳转(修改 location)
location.href = 'https://example.com'; // 跳转到新页面
location.assign('https://example.com'); // 同上,可跳转历史记录
location.replace('https://example.com'); // 替换当前页面(无历史记录)
location.reload(); // 重新加载当前页面
location.reload(true); // 强制从服务器重新加载(跳过缓存)
history — 浏览历史
// 前进后退
history.back(); // 后退一页
history.forward(); // 前进一页
history.go(-2); // 后退两页(正数则前进)
// HTML5 History API(单页应用常用)
history.pushState({ page: 1 }, 'Title', '?page=1'); // 添加历史记录,不刷新页面
history.replaceState({ page: 2 }, 'Title', '?page=2'); // 替换当前历史记录
// 监听历史变化
window.addEventListener('popstate', (event) => {
console.log('状态:', event.state);
});
screen — 屏幕信息
console.log(screen.width); // 屏幕宽度
console.log(screen.height); // 屏幕高度
console.log(screen.availWidth); // 可用宽度(扣除任务栏等)
console.log(screen.availHeight); // 可用高度
console.log(screen.colorDepth); // 颜色深度(如 24)
localStorage 和 sessionStorage
// localStorage — 持久化存储(除非手动清除,否则永久保存)
localStorage.setItem('theme', 'dark');
console.log(localStorage.getItem('theme')); // "dark"
localStorage.removeItem('theme');
localStorage.clear(); // 清空所有数据
// 存储对象(需要序列化)
let user = { name: 'Alice', age: 25 };
localStorage.setItem('user', JSON.stringify(user));
let savedUser = JSON.parse(localStorage.getItem('user'));
console.log(savedUser.name); // "Alice"
// sessionStorage — 会话存储(关闭标签页后清除)
sessionStorage.setItem('temp', 'value');
console.log(sessionStorage.getItem('temp')); // "value"
// 关闭标签页后数据自动清除
// 存储事件(其他标签页修改 storage 时触发)
window.addEventListener('storage', (event) => {
console.log('key:', event.key, 'old:', event.oldValue, 'new:', event.newValue);
});
| 特性 | localStorage | sessionStorage |
|---|---|---|
| 生命周期 | 永久(除非手动清除) | 标签页关闭后清除 |
| 作用域 | 同源的所有标签页 | 仅当前标签页 |
| 容量 | 约 5MB | 约 5MB |
| API | setItem/getItem/removeItem/clear |
同上 |
浏览器全局函数
定时器(setTimeout / setInterval)
// setTimeout — 延迟执行一次
let timer1 = setTimeout(() => {
console.log('1 秒后执行');
}, 1000);
clearTimeout(timer1); // 取消定时器
// setInterval — 循环执行
let timer2 = setInterval(() => {
console.log('每秒执行一次');
}, 1000);
clearInterval(timer2); // 停止循环
// requestAnimationFrame — 动画帧(浏览器专有)
// let frameId;
// function animate() {
// // 更新动画逻辑
// frameId = requestAnimationFrame(animate);
// }
// cancelAnimationFrame(frameId); // 停止动画
注意:更多定时器内容已添加在
js-builtins.md的"定时器函数"章节,包括setTimeoutvssetInterval对比、this指向、防抖节流实现等。
fetch — 网络请求(现代方式)
// 基本 GET 请求
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) throw new Error('请求失败');
return response.json(); // 解析 JSON
})
.then(data => console.log(data))
.catch(error => console.error('错误:', error));
// POST 请求
fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ name: 'Alice', age: 25 })
})
.then(response => response.json())
.then(data => console.log('创建成功:', data))
.catch(console.error);
// 使用 async/await
async function getData() {
try {
let response = await fetch('https://api.example.com/data');
let data = await response.json();
console.log(data);
} catch (error) {
console.error('请求失败:', error);
}
}
XMLHttpRequest(传统方式,了解即可)
let xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) { // 请求完成
if (xhr.status === 200) {
console.log(JSON.parse(xhr.responseText));
} else {
console.error('请求失败:', xhr.status);
}
}
};
xhr.send();
console 对象
console.log('普通日志'); // 普通输出
console.warn('警告信息'); // 黄色警告
console.error('错误信息'); // 红色错误
console.info('提示信息'); // 提示(部分浏览器同 log)
console.debug('调试信息'); // 调试
// 格式化输出
console.log('姓名: %s, 年龄: %d', 'Alice', 25); // 格式化字符串
console.log('%c红色文字', 'color: red; font-size: 20px'); // 样式(Chrome)
// 分组
console.group('用户详情');
console.log('姓名: Alice');
console.log('年龄: 25');
console.groupEnd();
// 计时
console.time('循环耗时');
for (let i = 0; i < 100000; i++) {}
console.timeEnd('循环耗时'); // 输出耗时
// 表格
console.table([{ name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }]);
// 断言
console.assert(1 === 2, '1 不等于 2'); // 条件为假时输出错误
Canvas(简要)
canvas 元素用于通过 JavaScript 绘制图形。
let canvas = document.getElementById('my-canvas');
let ctx = canvas.getContext('2d');
// 绘制矩形
ctx.fillStyle = 'blue';
ctx.fillRect(10, 10, 100, 50); // x, y, width, height
ctx.strokeStyle = 'red';
ctx.strokeRect(120, 10, 100, 50); // 描边矩形
// 绘制文本
ctx.font = '20px Arial';
ctx.fillStyle = 'black';
ctx.fillText('Hello Canvas', 10, 80);
// 绘制路径(线条)
ctx.beginPath();
ctx.moveTo(10, 100); // 起点
ctx.lineTo(100, 100); // 画线到
ctx.lineTo(100, 150);
ctx.stroke(); // 描边
WebSocket(简要)
WebSocket 提供浏览器与服务器之间的持久连接(全双工通信)。
// 创建 WebSocket 连接
let ws = new WebSocket('ws://localhost:8080');
// 连接建立
ws.onopen = () => {
console.log('连接已建立');
ws.send(JSON.stringify({ type: 'hello', data: 'Hello Server' }));
};
// 接收消息
ws.onmessage = (event) => {
console.log('收到消息:', event.data);
};
// 连接关闭
ws.onclose = (event) => {
console.log('连接关闭:', event.code, event.reason);
};
// 发生错误
ws.onerror = (error) => {
console.error('WebSocket 错误:', error);
};
Web Workers(简要)
Worker 允许在后台线程中运行脚本,不阻塞主线程。
// 主线程
let worker = new Worker('worker.js');
worker.postMessage({ type: 'start', data: [1, 2, 3] });
worker.onmessage = (event) => {
console.log('Worker 返回:', event.data);
};
worker.onerror = (error) => {
console.error('Worker 错误:', error);
};
// worker.js(单独的文件)
// self.addEventListener('message', (e) => {
// let result = e.data.data.map(x => x * 2);
// self.postMessage(result);
// });
综合示例
示例 1:DOM 操作 — 简易待办事项
// HTML:
// <input id="todo-input"><button id="add-btn">添加</button>
// <ul id="todo-list"></ul>
let input = document.getElementById('todo-input');
let button = document.getElementById('add-btn');
let list = document.getElementById('todo-list');
button.addEventListener('click', () => {
let text = input.value.trim();
if (!text) return;
let li = document.createElement('li');
li.textContent = text;
let removeBtn = document.createElement('button');
removeBtn.textContent = '删除';
removeBtn.addEventListener('click', () => li.remove());
li.appendChild(removeBtn);
list.appendChild(li);
input.value = '';
});
示例 2:AJAX 请求 + localStorage 缓存
async function fetchWithCache(url) {
let cacheKey = 'cache:' + url;
// 先检查缓存
let cached = localStorage.getItem(cacheKey);
if (cached) {
console.log('从缓存读取');
return JSON.parse(cached);
}
// 发起请求
try {
let response = await fetch(url);
if (!response.ok) throw new Error('请求失败');
let data = await response.json();
// 存入缓存(有效期 5 分钟)
let cacheData = { data, expiry: Date.now() + 5 * 60 * 1000 };
localStorage.setItem(cacheKey, JSON.stringify(cacheData));
return data;
} catch (error) {
console.error('请求失败:', error);
return null;
}
}
// 使用时检查缓存是否过期
function getCachedData(key) {
let cached = localStorage.getItem(key);
if (!cached) return null;
let { data, expiry } = JSON.parse(cached);
if (Date.now() > expiry) {
localStorage.removeItem(key);
return null; // 缓存过期
}
return data;
}
示例 3:监听页面可见性
// 当页面隐藏/显示时(切换标签页、最小化等)
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
console.log('页面被隐藏,暂停动画/视频');
} else {
console.log('页面重新可见,恢复动画/视频');
}
});
示例 4:表单验证 + 即时反馈
let emailInput = document.getElementById('email');
let feedback = document.getElementById('email-feedback');
emailInput.addEventListener('input', () => {
let email = emailInput.value;
if (!email) {
feedback.textContent = '邮箱不能为空';
feedback.style.color = 'red';
} else if (!email.includes('@')) {
feedback.textContent = '邮箱格式不正确';
feedback.style.color = 'red';
} else {
feedback.textContent = '✓ 格式正确';
feedback.style.color = 'green';
}
});
总结:浏览器特有 API 速查表
| 类别 | 主要对象/方法 | 说明 |
|---|---|---|
| 全局对象 | window |
浏览器全局对象 |
| 弹窗 | alert()、confirm()、prompt() |
不推荐用于生产环境 |
| DOM | document、getElementById()、querySelector() 等 |
操作网页元素 |
| 事件 | addEventListener()、removeEventListener() |
事件监听 |
| BOM - Navigator | navigator |
浏览器信息 |
| BOM - Location | location |
URL 操作 |
| BOM - History | history |
浏览历史 |
| BOM - Screen | screen |
屏幕信息 |
| 存储 | localStorage、sessionStorage |
本地存储 |
| 网络 | fetch()、XMLHttpRequest |
HTTP 请求 |
| 定时器 | setTimeout()、setInterval()、requestAnimationFrame() |
延迟/循环执行 |
| 调试 | console |
控制台输出 |
| 图形 | canvas |
2D/3D 绘图 |
| 通信 | WebSocket |
持久连接 |
| 多线程 | Worker |
后台线程 |
重要提示:本文档介绍的是浏览器特有的 API。ECMAScript 标准内置对象(Math、Date、JSON、Map、Set、Promise 等)请参考
js-builtins.md。