前言
作为一名前端开发者,每个人都是从小白过来的。在我们最开始接触JavaScript的时候,相信大家听到最多的知识点之一就是
DOM对象模型和BOM对象模型,
其中DOM就是我们的文档对象,也就是HTML元素等等,而BOM则是浏览器对象模型,更为准确的说应该是BOM是我们利用JavaScript开发Web应用的核心,它提供给我们可以操作浏览器的一些功能对象。
很多时候如果我们有的需求是针对于浏览器层面的,我们应该首要想到BOM对象,但是很多小伙伴却由于长期不接触而逐渐忘记,今天我们就将BOM捡起来,好好学习一番。
1.DOM和BOM
为了照顾初学的小伙伴,我们简单的介绍下DOM和BOM,以便更好的学习后面的BOM知识点。
首先我们需要知道两个的区别以及基本概念,总结如下。
DOM:
DOM又称文档对象模型,它是HTML和XML文档的编程接口,它主要描述了一些我们使用JS处理网页内容的方法和接口,它的目标是网页内容。比如说我们使用JS修改页面内容,其实就是操作的DOM文档。
BOM:
BOM又称浏览器对象模型,它主要用来描述一些与浏览器行为相关的接口和方法,比如我们利用JS调整浏览器窗口大小、标签页跳转等等,这些都是BOM对象。
对于初学者来说,可以理解DOM和BOM有一点点难,因为它们都是对象模型,不是真正存在的东西,它们似乎是一种规范。
为了更好的理解,我这里用最通俗的语言解释一下DOM和BOM。
最简单的理解:
大家可以把DOM和BOM想象成两个大箩筐,DOM箩筐里面装的是HTML、XHTML等等元素、属性和相关方法对象,而BOM箩筐内装的是浏览器的相关属性和方法对象。DOM和BOM这两个箩筐中都有一些核心对象或者方法,这就是我们需要学习的。
这样来解释是不是就很好理解了,我们要学会把虚拟的东西实物话,就像上学的时候做物理提时,我们要学会画图,把干瘪瘪的题目实物为图形。
前面既然说BOM对象模型是针对于浏览器的,那么它暴漏了哪些对象供我们使用呢?或者说我们如何操作浏览器呢?接下来我们就分别学习一下BOM暴漏给我们的一些对象。
2.window对象
window对象是BOM的核心对象,它表示的是浏览器的实例。它在我们的JS中则代表全局对象,即Global对象的意思,当然,既然是浏览器实例,我们就只能在网页中的JS内使用window,在普通ECMAscript中,window即Global对象。
既然是全局对象,意味着我们在网页中定义的所有全局变量、方法等都可以在window对象下找到。
我们可以讲window对象打印出来看看。
代码如下:
console.log(window)
复制代码
输出结果:
2.1 Global作用域
因为window代表的是ECMAscript中的Global对象,大家可以简单的讲window与Global划等号。所以如果使用var声明的全局变量或者方法,都将称为window对象的属性和方法。
代码如下:
var name = '小猪课堂';
var say = () => {
console.log('你好!小猪课堂');
}
console.log(name); // 小猪课堂
console.log(window.name); // 小猪课堂
say(); // 你好!小猪课堂
window.say(); // 你好!小猪课堂
复制代码
上段代码我们使用var声明全局变量和全局方法,然后使用window对象调用它们,这说明我们声明的这些变量和方法全都挂载到了window对象上去了。
需要注意的是:
如果我们使用let或者const声明方法时,该方法不会挂载到window对象上去,比如下列代码会报错:
let say = () => {
console.log('你好!小猪课堂');
}
window.say(); // Uncaught TypeError: window.say is not a function
复制代码
细心的小伙伴应该也发现了,我们声明的全局变量可以不适用window.say的形式调用,可以省略window,因为window是全局作用域,变量或方法找不到的时候自然要去window上找,所以我们挂载到window对象上的方法或变量通常可以直接调用,而不需要window.。
2.2 window窗口关系
每一个窗口都会存在一个window对象,那么这些window对象之间有没有什么关联呢?特别是在有时候我们在某一个网页窗口中,又打开了一个网页窗口,那么它们之间有没有联系呢?
window对象中有三个属性,这三个属性可以用来区别窗口之间的关联:
- window.top:顶层窗口,即最外层窗口
- window.parent:当前窗口的父窗口,如果当前窗口即顶层窗口,则window.top=window.parent。
- self:当前窗口
我们可以把这三个属性打印出来看看。
代码如下:
console.log(window.top);
console.log(window.parent);
console.log(window.self);
console.log(window.top == window.parent); // true
console.log(window.top == window.self); // true
复制代码
打印结果:
我们可以看到window的parent、top、self三个属性是相等的,因为我们这里只有一个窗口。你可是试试在当前也变打开新的窗口,然后再看看这三个属性的只,比如使用a标签打开。
2.3 窗口位置
window对象中提供了两个属性来获取当前窗口距离屏幕左侧和顶部的距离,单位为像素。
- screenLeft:窗口距离屏幕左侧的距离
- screenTop:窗口距离屏幕顶部的距离
示例代码:
console.log('screenLeft:', window.screenLeft);
console.log('screenTop:', window.screenTop);
复制代码
打印结果:
window对象内部还提供了两个方法将浏览器窗口移动到指定位置,当然,这两个方法根据浏览器的不同可能会被禁掉。
- moveTo:将窗口移动到指定坐标
- moveBy:将窗口向指定方向移动指定像素值
示例代码:
window.moveTo(200, 200); // 把窗口移动到坐标位置(200, 200)
window.moveBy(-50, 0); // 将窗口像做移动50像素
复制代码
2.4 窗口位置
window虽然提供了属性获取浏览器窗口的大小,但是在不同的浏览器中获取浏览器窗口大小都不是太容易,目前常见的浏览器通常提供一下4个属性获取浏览器窗口大小:
- innerWidth
- innerHeight
- outerWidth
- outerHeight
示例代码:
console.log(window.innerHeight);
console.log(window.innerWidth);
console.log(window.outerHeight);
console.log(window.outerWidth);
复制代码
输出结果:
可以看到在这里innerHeight和innerWidth代表的是浏览器可视窗口的大小,outerHeight和outerWidth表示的是浏览器窗口的大小。
但是在移动设备上,可视窗口的大小近乎等于浏览器窗口的大小。
在我们的实际开发中通常使用如下方法获取可视窗口的大小:
document.documentElement.clientHeight
document.documentElement.clientWidth
复制代码
2.5 视口位置
前面我们讲解的都是浏览器窗口的位置,其实window对象中还提供了方法用来控制可视窗口的位置,所谓视口就是可视区域,比如我们一个网页出现了横向或者纵向滚动条,那么它必然有些内容看不见。
这个时候我们可以手动滚动滚动条来让内容出现,我们也可以使用window提供的方法来让可视窗口变换位置。
- scrollBy:让视口像指定方向滚动多少像素值
- scrollTo:让视口滚动到指定坐标
示例代码:
window.scrollBy(0, 100); // 让视口向下滚动100px
window.scrollTo(0, 0); // 让视口滚动到页面左上角
复制代码
初次之前scrollTo方法还可以接收其它参数,比如控制滚动的时候是否平滑,感兴趣的小伙伴可以自行下来更加仔细的学习。
2.6 导航与打开新窗口
window对象提供了一个open()方法,它用于导航到指定URL,当然也可以是打开新窗口。open方法接收三个参数。
- window.open(url, target, str, bool)
-
- url:需要打开的url地址
- target:目标窗口,假如已经有目标窗口存在,则会在对应的窗口中打开该url
- str:一个特性字符串,主要是用来配置新窗口或者新标签页的浏览器特性,比如工具栏、窗台栏等等
- bool:一个布尔值,用来控制是否需要打开新的窗口。
我们通常只需要传前面三个参数即可,因为我们常见的需求就是打开一个新的标签页等等。
示例代码:
window.open('www.baidu.com', 'topFram') // 在目标窗口topFram中打开url
// 可以使用a标签实现
<a href="www.baidu.com" target="topFram"></a>
复制代码
2.7 window其它属性
前面我们介绍了几个window对象下的属性,其实window对象里面还有特别多的属性,而且我们经常用到,这里举例几个,大家看到这几个应该就能举一反三了。
- setTimeout、setInterval
- alert()
- parseInt()
…..
具体还有哪些属性大家可以打印window对象出来看看
3.location对象
location对象是BOM对象中非常有用的,可以说是最重要的特性之一,它主要提供了当前窗口中加载的文档信息,以及一些导航功能。location对象既是window的属性,也是document的属性。所以我们可以通过两种方式来获取它:
- window.location
- document.location
我们可以在window对象中找到它,如下图所示:
可以看到location对象中包含了很多有用的信息,大家可以根据需求自行获取。
3.1 查询字符串
在location中有一个属性很重要,它就是search属性,它的值就是url中包括?在内后后面所哟内容。
比如我们查看下面打印结果:
利用search我们就可以不用分割url便获得了url的查询字段,再借助字符串分割,我们就能很方便的获取url参数了。
3.2 操作url
location属性中有一个assign方法,该方法接收一个url地址,它会让我们的网页立即启动导航到新的url,而且还会再浏览器历史记录中增加一条记录。
示例代码:
location.assign('http://www.baidu.com');
复制代码
上段代码将会立即讲我们的页面跳转至指定url页面。
当然,细心的小伙伴可能发现location对象中的href属性便是当前url地址,我们是否可以更改此地址来达到跳转的目的呢?
实际上,上述代码的实现效果与下段代码的实现效果一致:
location.href = 'http://www.baidu.com'
或
location = 'http://www.baidu.com'
复制代码
4.navigator对象
BOM中提供了一个navigator对象,它主要用来获取浏览器的一些基础信息,比如版本、名称等信息。
navigator提供了特别多的属性,大家可以有需要的时候去查看每个属性代表的意义即可:
我们使用navigator属性时,通常就是为了确定浏览器的类型。
4.1 检测插件
我们经常上一些网站的时候会提示我们安装某些插件等等,它们是怎么知道我们没有安装某个插件呢?
这其实就要归功于navigator对象中plugins属性,plugins属性是一个数组,数组中的每一项都包含一下属性:
- name:插件名称
- description:插件介绍
- filename:插件文件名
- length:由当前插件处理的MIME类型数量
示例代码:
window.navigator.plugins
复制代码
5.screen对象
screen对象也是BOM对象中的属性之一,可以通过window.screen来调用。它主要用来存储客户端各种信息,由于用的比较少,我们可以给出它的每个属性代表什么,供大家参考。
我们也可以打印出来看看。
代码如下:
console.log(screen)
复制代码
打印结果:
6.history对象
history对象主要用来表示当前窗口的历史导航记录,但是由于安全考虑,我们时没法直接看到访问过的url,我们可以打印出来看看:
6.1 导航
history对象中有一个go方法,它可以控制浏览器的前进后退,它的参数为一个数字,代表的时浏览器前进或者后退多少步。
示例代码:
// 后退一页
history.go(-1)
// 前进一页
history.go(1)
// 前进两页
history.go(2)
复制代码
6.2 历史状态管理
在以前,我们每次变化url是则代表重新刷新页面,比如浏览器前进后退则代表刷新整个页面,这种用户体验是非常查的.
为了解决这类问题, 出现了hashChange事件,它会在页面url散列变化时被触发, 这个时候我们可以执行一些我们自己的操作. 对于hashChange事件需要比较复杂,需要大家自己下来补充这一块的知识.
而我们的history对象中有一个pushState方法, 该方法可以让开发者改变浏览器URL的时候不会加载新的页面. 该方法接收三个参数.
示例代码:
history.pushState(stateObject, "My title", "baz.html");
复制代码
pushState的具体使用方法和规则可以参考MDN:
pushState
这里不做过多介绍, 总之大叫需要知道pushState的作用即可:
pushState可以让我们的url改变时不刷新页面.
目前很多单页面应用的路由就是使用的这一原理, 后续我们也会推出文章专门讲解pushState.
总结
到这里我们介绍了BOM对象中的常见属性和方法, 大家有没有发现, 我们介绍的所有属性和方法都是在window对象下, 所以,大家到这里是否明白了BOM对象模型是什么呢?