什么是 BOM?#
BOM(Browser Object Model,浏览器对象模型)不同于操作文档的 DOM(Document Object Model),它提供了独立于内容、与浏览器窗口进行交互的对象。BOM 没有正式的标准(但存在一些事实标准),因此不同浏览器在实现上可能存在细微差异,但核心对象和方法是基本一致的。
BOM 的核心是 window 对象,它代表整个浏览器窗口,同时也在全局作用域中,所有全局变量和函数都成为其属性,甚至 document 也是它的一个属性。
- https://developer.mozilla.org/zh-CN/docs/Web/API/Window
- https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator
- https://developer.mozilla.org/zh-CN/docs/Web/API/Location
- https://developer.mozilla.org/zh-CN/docs/Web/API/History
- https://developer.mozilla.org/zh-CN/docs/Web/API/Screen
BOM API 分类整理#
以下是 BOM 的主要组成部分,按功能分类:
1. 窗口控制 (window)#
window 对象是 BOM 的顶层对象,所有其他 BOM 对象都是它的属性。
属性:
innerWidth/innerHeight: 浏览器窗口的视口(viewport)宽度/高度(包括滚动条)。outerWidth/outerHeight: 整个浏览器窗口的宽度/高度。scrollX/pageXOffset: 返回文档水平滚动的像素数(别名)。scrollY/pageYOffset: 返回文档垂直滚动的像素数(别名)。
方法:
alert(),confirm(),prompt(): 系统对话框。open(),close(): 打开和关闭浏览器窗口。setTimeout(),clearTimeout(): 在指定的毫秒数后执行一次代码。setInterval(),clearInterval(): 每隔指定的毫秒数重复执行代码。scrollTo(),scroll(): 滚动文档到指定位置。requestAnimationFrame(): 告诉浏览器希望执行一个动画,要求浏览器在下次重绘之前调用指定的回调函数更新动画。
代码示例:
// 获取视口尺寸
console.log(`视口宽度: ${window.innerWidth}px, 高度: ${window.innerHeight}px`);
// 获取滚动位置
window.addEventListener('scroll', () => {
console.log(`已滚动: X-${window.scrollX}, Y-${window.scrollY}`);
});
// 定时器
const timeoutId = setTimeout(() => {
console.log('这条消息将在 2 秒后显示一次');
}, 2000);
const intervalId = setInterval(() => {
console.log('这条消息每秒都会显示');
}, 1000);
// 5 秒后停止循环
setTimeout(() => {
clearInterval(intervalId);
}, 5000);
// 确认对话框
if (window.confirm('你确定要继续吗?')) {
console.log('用户点击了确定');
} else {
console.log('用户点击了取消');
}
// 打开一个新窗口(通常会被浏览器拦截,需要用户触发)
document.getElementById('myButton').addEventListener('click', () => {
const newWindow = window.open('https://www.example.com', 'exampleWindow', 'width=600,height=400');
// 2秒后关闭它
setTimeout(() => newWindow.close(), 2000);
});
// 平滑滚动到页面顶部
window.scrollTo({
top: 0,
behavior: 'smooth'
});2. 浏览器信息 (navigator)#
navigator 对象提供了关于浏览器和操作系统的信息。
- 属性:
userAgent: 返回浏览器的用户代理字符串。platform: 返回运行浏览器的操作系统平台。language: 返回浏览器的首选语言。cookieEnabled: 返回浏览器是否启用 cookie。onLine: 返回浏览器是否联网。geolocation: 提供对设备地理位置的访问(需要用户授权)。
代码示例:
// 获取浏览器和系统信息
console.log(`用户代理: ${navigator.userAgent}`);
console.log(`操作系统: ${navigator.platform}`);
console.log(`浏览器语言: ${navigator.language}`);
console.log(`Cookie 是否启用: ${navigator.cookieEnabled}`);
console.log(`是否在线: ${navigator.onLine}`);
// 地理定位(需要 HTTPS 环境或在 localhost 下)
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => { // 成功回调
console.log(`纬度: ${position.coords.latitude}`);
console.log(`经度: ${position.coords.longitude}`);
console.log(`精度: ${position.coords.accuracy} 米`);
},
(error) => { // 失败回调
console.error(`获取位置失败 (${error.code}): ${error.message}`);
},
{ // 选项
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
}
);
} else {
console.error('该浏览器不支持地理定位功能');
}3. 地址信息 (location)#
location 对象包含了当前文档的 URL 信息,并且可以用于重定向和刷新页面。
属性:
href: 设置或返回完整的 URL。protocol: 设置或返回 URL 的协议(如http:)。host: 设置或返回主机名和端口号(如www.example.com:8080)。hostname: 设置或返回主机名(如www.example.com)。port: 设置或返回端口号。pathname: 设置或返回 URL 的路径部分(如/path/page.html)。search: 设置或返回 URL 的查询字符串(问号?之后的部分)。hash: 设置或返回 URL 的锚点部分(井号#之后的部分)。
方法:
assign(url): 加载新文档。reload(force): 重新加载当前文档。force为true时从服务器强制重新加载。replace(url): 用新文档替换当前文档(不会在历史记录中生成新记录)。
代码示例:
// 解析当前 URL
console.log(`完整 URL: ${location.href}`);
console.log(`协议: ${location.protocol}`);
console.log(`主机: ${location.host}`);
console.log(`路径: ${location.pathname}`);
console.log(`查询参数: ${location.search}`);
console.log(`哈希: ${location.hash}`);
// 解析查询字符串 (例如: ?name=John&age=30)
const urlParams = new URLSearchParams(location.search);
const name = urlParams.get('name'); // "John"
const age = urlParams.get('age'); // "30"
console.log(`参数 name: ${name}, age: ${age}`);
// 页面导航
// location.assign('https://www.newsite.com'); // 跳转到新页面,可回退
// 重定向(替换当前历史记录)
// location.replace('https://www.newsite.com'); // 跳转到新页面,不可回退
// 刷新页面
// location.reload(); // 可能从缓存 reload
// location.reload(true); // 从服务器强制 reload
4. 浏览历史 (history)#
history 对象提供了与浏览器会话历史交互的接口。
属性:
length: 返回会话历史中的记录数量。
方法:
back(): 回退到历史记录中的上一个页面(等同于点击浏览器的后退按钮)。forward(): 前进到历史记录中的下一个页面(等同于点击浏览器的前进按钮)。go(n): 在历史记录中前进或后退n步。go(-1)等同于back()。pushState(state, title[, url]): 向历史记录栈添加一个状态,不刷新页面。replaceState(state, title[, url]): 修改当前历史记录条目,不刷新页面。
代码示例:
// 历史记录长度
console.log(`历史记录数: ${history.length}`);
// 导航
// history.back(); // 后退一页
// history.forward(); // 前进一页
// history.go(-2); // 后退两页
// 添加和修改历史记录(用于单页面应用 SPA)
// 假设当前 URL 是 /page1.html
history.pushState({userId: 123}, '', '/page2.html'); // URL 变为 /page2.html,但不加载它
// 此时可以手动更新页面内容为“page2”的内容
// 监听 popstate 事件,当用户点击前进/后退按钮时触发
window.addEventListener('popstate', (event) => {
// event.state 是 pushState 时传入的 state 对象
console.log('位置变化了', event.state);
// 根据 event.state 或 location 更新页面内容
});5. 屏幕信息 (screen)#
screen 对象提供了用户屏幕的信息。
- 属性:
width/height: 屏幕的总宽度/高度。availWidth/availHeight: 屏幕的可用宽度/高度(不包括任务栏等)。colorDepth: 返回颜色深度(如 24)。pixelDepth: 返回屏幕的像素深度(通常与 colorDepth 相同)。
代码示例:
// 获取屏幕信息
console.log(`屏幕分辨率: ${screen.width}x${screen.height}`);
console.log(`可用区域: ${screen.availWidth}x${screen.availHeight}`);
console.log(`色彩深度: ${screen.colorDepth} 位`);
// 可以根据屏幕信息调整窗口位置或大小
const left = (screen.width - 600) / 2; // 居中一个 600px 宽的窗口
const top = (screen.height - 400) / 2; // 居中一个 400px 高的窗口
// window.open('popup.html', '_blank', `width=600,height=400,left=${left},top=${top}`);
总结#
| 分类 | 核心对象 | 主要用途 |
|---|---|---|
| 窗口控制 | window | 操作浏览器窗口、定时器、对话框、滚动 |
| 浏览器信息 | navigator | 获取浏览器、操作系统、网络状态、地理位置 |
| 地址信息 | location | 获取和操作当前页面的 URL,进行页面重定向 |
| 浏览历史 | history | 在用户的浏览历史记录中前进和后退(SPA 核心) |
| 屏幕信息 | screen | 获取用户显示器的尺寸和色彩信息 |
BOM 虽然不像 DOM 那样有严格的标准,但它是 Web 开发中不可或缺的一部分,用于实现与浏览器本身而非文档内容相关的复杂交互功能。
API 列表#
window.matchMedia#
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia
const userPrefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;