03BOM 浏览器环境

DOM 管「页面里的东西」,BOM(Browser Object Model)管「浏览器本身」: 地址栏、历史记录、窗口尺寸、定时器、存储。 做单页应用、多页跳转、记住用户偏好,都绕不开它。

约 14 分钟 4 个动手实验 浏览器 API

一、BOM 地图:挂在 window 上

window

全局对象。变量、定时器、弹窗、尺寸都挂这里。浏览器里 window === globalThis。

location

地址栏:URL 解析、跳转、刷新、hash 查询参数。

history

前进 / 后退 / 替换当前记录(SPA 路由基础)。

navigator

UA、语言、在线状态、剪贴板、地理信息(注意隐私)。

screen / innerWidth

屏幕与视口尺寸。响应式检测、弹层定位要用。

localStorage / sessionStorage

键值存储(08 章学过),BOM 侧的「记忆」。

二、location:读 URL 与跳转

属性 / 方法含义示例
location.href完整 URL(可赋值跳转)location.href = '/home'
location.pathname路径/user/1
location.search查询串(含 ?)?id=1&q=js
location.hash锚点(含 #)#sec-2
location.reload()刷新location.reload(true)
location.assign(url)跳转(可后退)—
location.replace(url)替换(不可后退)登录后跳首页
解析查询参数:① 读 search/hash;② 用 URLSearchParams;③ 改 hash(不刷新页面)

三、history:前进后退与替换

pushState 会多一条历史记录(可后退); replaceState 换掉当前这条(不可后退)。 登录后跳转、分页筛选,常用 replaceState,避免用户后退又回到登录页。

四、窗口尺寸与弹层定位

读视口 / 屏幕 / 设备像素比,判断是否移动端:① innerWidth ② matchMedia ③ devicePixelRatio
判断移动端优先 matchMedia, 不要用 UA 字符串硬解析——平板、折叠屏、桌面缩放都会骗过 UA。

五、定时器家族(和事件循环连起来)

API用途注意
setTimeout延迟一次嵌套有 4ms 节流;返回 id 用于 clear
setInterval周期重复容易漏 clear 造成泄漏;回调积压
requestAnimationFrame帧同步动画标签隐藏时暂停,省电
requestIdleCallback空闲时做次要任务兼容性一般,可 polyfill

六、常见问题 · 自问自答

Q

为什么刷新页面后表单内容 / 展开状态丢了?

A

内存变量不会跨刷新。把需要记住的状态写进 localStorage(长期)或 sessionStorage(当前标签); 也可以把状态编码进 location.hash / query,刷新后还能恢复。

Q

location.assign 和 replace 有什么差别?

A

assign 像点了个链接——历史里多一条,用户能「后退」回来; replace 把当前记录换掉,后退会跳过这一页。 登录成功跳首页用 replace,免得后退又回到登录表单。

Q

setInterval 为什么越跑越卡?

A

回调执行时间若大于间隔,会排队积压。 改用 setTimeout 递归(上次做完再排下次),或动画交给 requestAnimationFrame。组件销毁记得 clearInterval。

Q

怎么判断用户手机还是电脑?

A

布局相关:用 matchMedia('(pointer: coarse)') / matchMedia('(max-width: 768px)')。 只有做「下载 App 提示」这类产品逻辑才看 navigator.userAgent, 且要做好兜底。

Q

为什么我的 history.pushState 改了 URL 页面却没变?

A

这是预期行为:pushState只改地址和历史栈,不加载新文档。 路由变化要自己监听 popstate 并渲染。真正刷新要用 location.href。

七、本章小结

  • BOM 挂在 window 上:location / history / navigator / 尺寸 / 定时器。
  • 读查询串用 URLSearchParams;跳转分清 assign 与 replace。
  • SPA 靠 pushState + popstate,不刷新换页。
  • 响应式判断用 matchMedia;定时器用完必 clear。
  • 要跨刷新的状态 → localStorage 或 URL。
动手练习: ① 从 ?id=1 读出 id 并显示在标题; ② 做一个「记住侧边栏折叠状态」(localStorage); ③ 用 pushState/replaceState 演示后退行为差异。