BOM (Browser Object Model),即浏览器对象模型。BOM提供了很多接口用于操作浏览器的各种功能,这些功能与任何网页内容无关,所以说BOM的主要用途就是操作浏览器
Window
window 对象是 BOM 提供的通过 JavaScript 访问浏览器窗口的一个接口,也是 ECMAScript 规定的 Global 对象(全局对象)。
在全局作用域下,当使用var声明变量时,变量会自动挂载到window对象下;而使用let或const声明的变量则不会自动挂载到window下:
const a = 1
console.log(window.a) // undefined
var b = 2
console.log(window.b) // 2
另外,使用function声明的函数变量,还是会挂载到window下
function c(){ return false }
console.log(window.c) // ƒ c(){return false}
窗口关系
在存在 <iframe>嵌套的网页上,我们可能会需要判断窗口之间的关系,BOM 提供了以下几个属性来表示窗口关系:
window.parent表示当前窗口的父窗口window.top表示最外层窗口window.self表示window对象本身
窗口位置
window.screenLeft和window.screenTop用于表示浏览器窗口相对于屏幕左侧和顶部的位置 ,返回值的单位是CSS像素。window.moveTo()和window.moveBy()方法可以移动窗口至指定的位置
窗口大小
outerWidth和outerHeight返回浏览器窗口自身的大小(不管是在最外层 window 上使用,还是在 iframe 中使用)innerWidth和innerHeight返回浏览器窗口中页面可视区域的大小(不包含浏览器边框和工具栏)window.resizeTo()和window.resizeBy()方法可以调整窗口大小,resizeTo()接收新的宽度和高度值,而resizeBy()接收宽度和高度各要缩放多少
调整窗口位置和大小的方法,大多数浏览器默认都是禁用的,实测 Chrome 中控制台中直接调用没有任何响应。
视口位置
先解释下“视口”的意思,视口即 view-port,指的是浏览器的可视区域,说白了就是整个浏览器页面(不包括工具栏和底栏),因为网页上的内容常常很多,导致我们需要滚动页面来查看内容,滚动网页就相当于滚动视口。
window.scrollTo()和window.scrollBy()方法可以使视口滚动,例如:
// 接受2个参数,分别是X-水平距离和Y-垂直距离
// 相对于当前视口向下滚动100像素
window.scrollBy(0, 100);
// 滚动到页面左上角
window.scrollTo(0, 0);
也可以传入一个配置对象来实现平滑滚动:
window.scrollTo({
left: 100,
top: 100,
behavior: 'smooth' // 有 auto 和 smooth 两个可选值
});
上面的方法没有被禁用,可以很方便的调用。
窗口导航
window.open()方法可以用于导航到指定 URL,也可以用于打开新浏览器窗口,它会创建一个新的浏览器窗口对象,与右键菜单中的新建窗口选项作用相同。
这个方法接收3个参数:
url:要跳转的目标链接地址strWindowName:新窗口的名称(并不是新窗口的浏览器tab的标题),可以用来作为<a>或<form>的目标属性值,不能含有空白字符strWindowFeatures:一个字符串,列出了将要打开的窗口的一些特性(窗口大小、位置、是否显示菜单栏等等) ,字符串中不能包含任何空白字符,特性之间用逗号分隔开。
window.open("http://www.bing.com/",
"bingWindow",
"height=400,width=400,top=10,left=10,resizable=yes");
window.open的返回值是新建窗口的引用,如果新建的窗口与当前窗口满足同源策略,那么就可以访问到其中的属性或方法。
定时器
setTimeout(callback, time),在等待time毫秒数之后执行回调函数callback,通过clearTimeout来清除定时器setInterval(callback, time),每隔time毫秒数就执行回调函数callback,通过clearInterval来清除定时器
使用setTimeout是设置循环任务的推荐做法。setInterval()在实践中很少会在生产环境下使用,因为一个任务结束和下一个任务开始之间的时间间隔是无法保证的,有些循环定时任务可能会因此而被跳过。一般来说,最好不要使用setInterval,而是使用 setTimeout替换实现。
Navigator
window.navigator 用于查询浏览器的相关信息。它最常用的用途是返回当前浏览器的用户代理(user agent)字符串。通过在浏览器的移动端设备模拟中切换设备类型,可以看到不同的 user agent (UA)。 navigator.userAgent 可以获取访问当前的设备类型信息,主要有以下用途:
- 统计用户浏览器使用情况。通过判断每个 IP 的 UA 来确定这个IP是用什么浏览器访问的,以得到使用量的数据
- 根据用户使用浏览器的不同,显示不同的排版从而为用户提供更好的体验。有些网站会根据这个来调整打开网站的类型,如果是移动设备就打开wap 页面,显示非手机的就打开 pc 常规页面
Screen
window.screen 在实际开发中用的比较少,不过了解一下还是可以的,它保存的纯粹浏览器窗口外面的客户端显示器的信息,比如像素宽度和像素高度:
availWidth:返回窗口中水平方向可用空间的像素值colorDepth:返回屏幕的色彩深度height:以像素为单位返回屏幕的高度orientation:返回当前屏幕的转向
Location
window.location 是最有用的 BOM 对象之一,提供了当前窗口中加载文档的信息,以及通常的导航功能。它既是 window 的属性,也是 document 的属性,window.location和document.location 指向同一个对象。
属性
修改地址
要修改现有的页面地址有很多方法,常用的包括下面的几种方式:
- location.assign(url) 传入一个 url 链接之后,导航到新 URL 的页面,同时在浏览器历史记录中增加一条
- window.location & location.href 直接将 url 赋值给 location 或者 location.href 也能实现页面跳转
- location.hash
指定 location.hash 的值也可以改变当面页面 url 连接中
#号部分之后的内容,常用于实现局部页面的切换 - location.replace(url) 前面几种方式修改页面 url 之后会体现在浏览器历史记录中,这样页面 url 修改后还可以回退到之前的页面;而使用 replace 跳转页面以后,将不会在历史记录中保存,它会替换当前 url 而不是新建,所以也就不能回退
- location.reload(flag)
reload 可以重新加载当前页面,参数 flag 是一个布尔值,不传参数或者传入
false,浏览器会自己做出判断是否从缓存中加载页面;如果为 true,则强制浏览器从服务器重新请求页面
锚点定位
如果需要滚动到页面指定位置,可以通过给元素添加锚点,然后通过指定 href 来实现,例如现在要滚动到页面的第 22 个段落处 <p id="p22">这是需要滚动的目标位置</p>,可以这样:
// 第一种方法: # 表示锚点,后面接 id 的值
location.href = "#p22"
// 第二种方法:可以通过 a 标签
<a href="#p22"></a>
跳转到锚点位置以后,浏览器地址栏中的 URL 最后面会加上 #p22
URL 查询参数解析
URLSearchParams 提供了一组标准 API 方法,通过它们可以检查和修改查询字符串。给 URLSearchParams 构造函数传入一个查询字符串,就可以创建一个实例。这个实例提供了get()、set()、delete()方法,可以对查询字符串执行相应操作
let queryStr = "http://www.bing.com?q=javascript&num=10";
let searchParams = new URLSearchParams(queryStr);
// 获取 URL 中的查询参数字符串
searchParams.toString(); // "q=javascript&num=10"
// 检测是否存在某个参数
searchParams.has("num"); // true
// 获取某个参数的值
searchParams.get("num"); // 10
// 设置某个参数的值
searchParams.set("page", "3");
searchParams.toString(); // "http://www.bing.com?q=javascript&num=10&page=3"
// 删除某个参数
searchParams.delete("q");
searchParams.toString(); // "http://www.bing.com?num=10&page=3"
History
window.history 对象表示当前窗口首次使用以来用户的导航历史记录,出于安全考虑,这个对象不会暴露用户访问过的 URL。通过 history 可以实现在不刷新页面的前提下动态改变浏览器地址栏中的URL地址,从而动态修改页面上所显示的资源。
导航
- history.go() 可以在用户历史记录中沿任何方向导航,可以前进也可以后退。这个方法只接收一个参数,表示前进或后退多少步。负值表示在历史记录中后退(类似点击浏览器的“后退”按钮),而正值表示在历史记录中前进(类似点击浏览器的“前进”按钮)
// 后退一页
history.go(-1);
// 前进一页
history.go(1);
// 前进两页
history.go(2);
- history.back() & history.forward() 是 go 方法的两个特例,back() 可以在历史记录中后退 1 步,相当于 go(-1);forward() 可以前进 1 一步,相当于 go(1)
- history.length 这个属性可以返回当前页面(即当前这个浏览器标签页内)总共产生的历史记录的条数
历史状态管理
- hashchange 事件监听函数,在当前页面的 URL 发生改变时会被触发
- popstate
事件监听,历史记录发生改变时触发,调用
history.pushState()或者history.replaceState()不会触发popstate事件 - history.pushState(state, title, url)
添加一条历史记录,但不刷新页面(不会触发
hashchange事件,但会触发popstate事件)。- 参数
state是一个对象,用于指定网址相关的状态对象。 - 参数
title指定新页面的标题,但是所有浏览器目前都忽略这个值,因此这里可以填null。 - 参数
url用于指定新历史记录条目的 URL,必须与当前页面同源,否则会报错。
- 参数
- history.replaceState()
与
pushState()唯一的不同在于,pushState()会创建新的历史记录,而replaceState()只会替换当前的历史记录,同样也不会触发hashchange事件