Appearance
浏览器对象模型(BOM)
一、BOM概述
1.1 什么是BOM?
BOM (Browser Object Model) 提供了独立于内容而与浏览器窗口进行交互的对象,核心对象是window。
javascript
// BOM的层级结构
window
├── document (DOM)
├── location (URL定位与导航)
├── navigation (浏览器信息)
├── screen (屏幕信息)
├── history (历史记录)
└── frames (框架)
1.2 BOM与DOM的区别
javascript
// DOM - 文档对象模型
document.querySelector('.className');
document.getElementById('myId');
// BOM - 浏览器对象模型
window.innerHeight;
window.location.href;
二、Window对象详解
2.1 全局作用域
javascript
// window作为全局对象
var globalVar = 'global';
function globalFunc() { }
console.log(window.globalVar); // 'global'
console.log(window.globalFunc); // ƒ globalFunc() { }
// 但let和const声明的变量不会挂载到window
let letVar = 'let';
console.log(window.letVar); // undefined
2.2 窗口操作
javascript
// 窗口大小
const pageWidth = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
// 视口位置
function scrollToTop() {
if (window.pageYOffset) {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
}
}
// 窗口打开与关闭
const popup = window.open('about:blank', 'popup', `
width=400,
height=400,
left=${(screen.width - 400) / 2},
top=${(screen.height - 400) / 2}
`);
// 安全检查
if (popup && !popup.closed) {
popup.document.write('<h1>Popup Content</h1>');
}
三、Location对象高级应用
3.1 URL解析与操作
javascript
// URL解析器
class URLParser {
constructor(url) {
this.parser = document.createElement('a');
this.parser.href = url;
}
get protocol() {
return this.parser.protocol.replace(':', '');
}
get hostname() {
return this.parser.hostname;
}
get query() {
const params = new URLSearchParams(this.parser.search);
return Object.fromEntries(params.entries());
}
}
// 使用示例
const parser = new URLParser('https://example.com:8080/path?name=test#hash');
console.log(parser.protocol); // 'https'
console.log(parser.query); // { name: 'test' }
3.2 导航增强
javascript
class Navigator {
static pushState(url, title = '', state = {}) {
if (window.history.pushState) {
window.history.pushState(state, title, url);
return true;
}
location.href = url;
return false;
}
static redirect(url, options = {}) {
const {
replace = false,
timeout = 0,
callback
} = options;
setTimeout(() => {
if (replace) {
location.replace(url);
} else {
location.href = url;
}
callback?.();
}, timeout);
}
}
四、Navigator对象与特性检测
4.1 浏览器检测
javascript
class BrowserDetector {
static get userAgent() {
return navigator.userAgent;
}
static get isChrome() {
return /Chrome/.test(this.userAgent) && /Google/.test(navigator.vendor);
}
static get isSafari() {
return /Safari/.test(this.userAgent) && /Apple/.test(navigator.vendor);
}
static get isFirefox() {
return /Firefox/.test(this.userAgent);
}
static get isEdge() {
return /Edg/.test(this.userAgent);
}
static get isMobile() {
return /Mobile/.test(this.userAgent);
}
}
4.2 特性检测
javascript
class FeatureDetector {
static checkAPI(api) {
return api in window;
}
static get features() {
return {
localStorage: this.checkAPI('localStorage'),
serviceWorker: this.checkAPI('serviceWorker'),
geolocation: this.checkAPI('navigator.geolocation'),
webGL: () => {
try {
return !!document.createElement('canvas')
.getContext('webgl');
} catch(e) {
return false;
}
}
};
}
}
五、Screen对象与响应式设计
javascript
class ScreenHelper {
static get screenInfo() {
return {
width: screen.width,
height: screen.height,
availWidth: screen.availWidth,
availHeight: screen.availHeight,
colorDepth: screen.colorDepth,
orientation: screen.orientation.type
};
}
static watchOrientation(callback) {
screen.orientation.addEventListener('change', () => {
callback(screen.orientation.type);
});
}
}
六、History API与状态管理
javascript
class HistoryManager {
constructor() {
this.handlers = new Map();
window.addEventListener('popstate', this.handlePopState.bind(this));
}
push(url, state = {}) {
history.pushState(state, '', url);
this.handleStateChange(state);
}
replace(url, state = {}) {
history.replaceState(state, '', url);
this.handleStateChange(state);
}
registerHandler(key, handler) {
this.handlers.set(key, handler);
}
handlePopState(event) {
this.handleStateChange(event.state);
}
handleStateChange(state) {
if (!state) return;
for (const [key, handler] of this.handlers) {
if (state[key]) {
handler(state[key]);
}
}
}
}
// 使用示例
const historyManager = new HistoryManager();
historyManager.registerHandler('page', (pageData) => {
console.log('Page changed:', pageData);
});
historyManager.push('/new-page', {
page: { id: 1, title: 'New Page' }
});
七、最佳实践
7.1 性能优化
javascript
// 防抖动的resize监听
function debounceResize(callback, delay = 250) {
let timeoutId;
window.addEventListener('resize', () => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
callback({
width: window.innerWidth,
height: window.innerHeight
});
}, delay);
});
}
7.2 安全考虑
javascript
// 安全的window.open
function safeWindowOpen(url, name, features) {
// 检查URL
if (!/^https?:\/\//i.test(url)) {
throw new Error('Invalid URL protocol');
}
const popup = window.open(url, name, features);
// 检查popup是否被阻止
if (popup === null) {
console.warn('Popup was blocked');
return null;
}
// 添加安全限制
popup.opener = null;
return popup;
}
总结
- BOM提供了与浏览器交互的核心API
- 正确使用BOM可以:
- 实现复杂的导航逻辑
- 管理浏览器窗口
- 检测浏览器特性
- 响应用户操作
- 开发中需注意:
- 浏览器兼容性
- 性能优化
- 安全限制
- 用户体验