1. 浏览器对象模型(BOM)基础认知
当我们在浏览器中打开开发者工具敲下window时,控制台输出的那个庞然大物就是BOM的具象化体现。作为前端开发者,每天打交道的远不止DOM(文档对象模型),那些控制浏览器窗口、访问屏幕尺寸、操作历史记录的能力,全都来自这个被称为Browser Object Model的体系。
BOM与DOM最大的区别在于:DOM处理的是文档内容,而BOM处理的是浏览器本身。举个例子,当我们需要获取用户屏幕分辨率时,用的是window.screen;当需要跳转页面时,调用的是window.location。这些不属于文档结构的操作,正是BOM的职责范围。
2. 核心BOM对象详解
2.1 window对象:全局掌门人
作为BOM的顶层对象,window有几点特殊之处值得注意:
- 全局变量会自动成为window的属性(如
var a = 1可通过window.a访问) - 窗口操作方法是高频使用功能:
// 新窗口操作 const newWin = window.open('about:blank') newWin.close() // 需要用户手势触发 // 窗口尺寸获取 const outerWidth = window.outerWidth // 包含浏览器边框 const innerWidth = window.innerWidth // 仅内容区域实际开发中要注意:移动端
innerWidth与视觉视口相关,可能受viewport缩放影响
2.2 location对象:URL操控大师
这个对象藏着许多开发者不知道的实用技巧:
// 解析当前URL const { hash, // "#section1" host, // "example.com:8080" hostname, // "example.com" href, // 完整URL origin, // "https://example.com" pathname, // "/path/page.html" port, // "8080" protocol, // "https:" search // "?id=123" } = location // 修改URL的三种方式 location.assign('new.html') // 记录历史 location.replace('new.html') // 不记录历史 location.reload(true) // 强制从服务器刷新2.3 navigator对象:设备信息宝库
现代浏览器中,navigator能提供的信息远超想象:
// 用户代理检测(不推荐特性检测) const isMobile = /Mobi|Android/i.test(navigator.userAgent) // 更可靠的特性检测 const isOnline = navigator.onLine const batterySupport = 'getBattery' in navigator // 硬件能力检测 const { hardwareConcurrency } = navigator // CPU核心数 const { deviceMemory } = navigator // 内存大小(GB) // 现代API示例 navigator.geolocation.getCurrentPosition(pos => { console.log(pos.coords.latitude, pos.coords.longitude) })2.4 history对象:单页应用基石
Vue Router/React Router的核心原理就构建在此之上:
// 基础操作 history.length // 历史记录数 history.back() // 等同于浏览器后退 history.forward() // 前进 history.go(-2) // 后退两步 // 现代API history.pushState({id:1}, '', '/product') // 添加记录 history.replaceState({id:2}, '', '/detail')// 替换当前记录 // 监听变化 window.addEventListener('popstate', e => { console.log('State changed:', e.state) })2.5 screen对象:显示设备探针
在做响应式设计时特别有用:
const { availWidth, // 可用宽度(除任务栏等) availHeight, // 可用高度 width, // 总宽度 height, // 总高度 colorDepth, // 颜色位数 pixelDepth, // 像素深度 orientation // 屏幕方向 } = screen // 检测屏幕旋转 screen.orientation.addEventListener('change', () => { console.log(`当前方向: ${screen.orientation.type}`) })3. 非常用但重要的BOM对象
3.1 performance对象:性能监控利器
前端监控系统的核心数据来源:
// 关键时间节点 const timing = performance.timing const loadTime = timing.loadEventEnd - timing.navigationStart // 资源计时 performance.getEntries().forEach(entry => { console.log(`${entry.name} 加载耗时: ${entry.duration}ms`) }) // 内存监测(Chrome专属) if (performance.memory) { console.log(`已用堆内存: ${performance.memory.usedJSHeapSize}`) }3.2 localStorage/sessionStorage:本地存储双雄
两者的区别常被面试官问到:
// 容量测试(实际约5MB) try { localStorage.setItem('test', new Array(5*1024*1024).join('a')) } catch(e) { console.log('超出存储限制') } // 实用封装 const storage = { set(key, val) { localStorage.setItem(key, JSON.stringify(val)) }, get(key) { const val = localStorage.getItem(key) return val ? JSON.parse(val) : null } } // 监听变化(同源页面间) window.addEventListener('storage', e => { console.log(`${e.key} 从 ${e.oldValue} 变为 ${e.newValue}`) })4. BOM实战技巧与陷阱
4.1 跨浏览器兼容方案
不同浏览器对BOM的实现差异处理:
// 标准化requestAnimationFrame const animFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame // 全屏API处理 function toggleFullscreen() { const docEl = document.documentElement const requestFS = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullscreen requestFS.call(docEl) }4.2 安全限制与应对
现代浏览器的安全策略越来越严格:
- 弹出窗口必须由用户手势触发
- 第三方cookie限制影响
document.cookie - 地理位置API需要HTTPS环境
- 存储配额可能被自动清理
4.3 性能优化要点
BOM操作不当会导致性能问题:
// 错误示例:频繁读取导致布局抖动 function resizeHandler() { const width = window.innerWidth const height = window.innerHeight // 使用width/height进行DOM操作 } // 正确做法:使用防抖+批量读取 const debounceResize = _.debounce(() => { const rect = { width: window.innerWidth, height: window.innerHeight } // 统一处理 }, 200) window.addEventListener('resize', debounceResize)5. 现代BOM API演进
5.1 新一代设备API
// 电池状态 navigator.getBattery().then(battery => { console.log(`电量: ${battery.level * 100}%`) }) // 网络状态 navigator.connection.addEventListener('change', () => { console.log(`网络类型: ${navigator.connection.effectiveType}`) }) // 剪贴板API navigator.clipboard.writeText('复制内容').then(() => { console.log('复制成功') })5.2 视觉视图控制
// 检测暗色模式 const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches // 监听设备姿态 window.addEventListener('deviceorientation', e => { console.log(`Alpha: ${e.alpha}, Beta: ${e.beta}, Gamma: ${e.gamma}`) }) // 屏幕唤醒锁定 let wakeLock = null async function keepAwake() { try { wakeLock = await navigator.wakeLock.request('screen') } catch(err) { console.error('唤醒锁定失败:', err) } }掌握BOM对象就像获得了浏览器的控制面板,从基础的页面跳转到高级的设备功能访问,这些API构成了现代Web应用的基础能力。建议定期查看MDN文档,因为浏览器正在不断扩展这些能力,比如最近新增的Contact Picker API、Badging API等都值得关注。