前言
这两天小落落读《JavaScrpit高级程序设计》(第三版)依然读到了很多的知识盲点,以此篇作一个记录。如有错误也希望大家指正。
BOM对象是什么
BOM(Browser Object Model 浏览器对象模型)
BOM提供了很多对象,用来访问浏览器的功能,而这些功能与任何的网页内容无关。
EcmaScript的核心 是JavaScript,而BOM无疑是JavaScript的核心。
BOM对象上的属性
我们先以一张图来表示BOM对象上的属性。
BOM是用来访问浏览器的功能。那么,对于BOM来说,window便是BOM的核心对象。
2.1 Window
window对象是一个比较特殊的存在。在浏览器当中,window对象既是JavaScrpt访问浏览器窗口的一个接口,又是ECMAScript规定的全局对象。
window在浏览器的具体功能:
全局作用域、窗口关系及框架、窗口位置、窗口大小、导航和打开窗口、间歇调用和超时调用、系统对话框
2.1.1 全局作用域
由于window对象在浏览器中是代表一个全局对象。因此所有在全局中定义的变量、函数、方法都会是window对象的属性和方法。
以下为例:
var age = 29;
function sayAge(){
alert(this.age)
}
console.log(window.age)
window.sayAge();
我们在全局中定义了一个变量age,以及一个函数sayAge。它们就会自动变成window对象的属性或者方法。所以我们可以通过window. 的形式对它们进行调用。
知识点:
1、虽然定义在全局的变量 就会变成window对象的属性。但与直接定义window对象的属性还是不同的。
直接定义的全局变量不能使用delete删除。
因为使用var定义的变量都有一个Configurable的特性,这个特性的值被设置为false,所以这样定义的属性不能被delete删除。
2、IE9以下版本,使用delete删除哪种定义的属性方法,都会抛出错误。
2.1.2 窗口关系及框架
如果页面中存在框架frame。那么每一个框架都有自己的window对象。并且每个框架的window对象是相互独立的。
在frame集中,可以通过数值索引(从0开始,从上到下,从左到右)或者框架的名称来访问相应的window对象。
如下代码
<frameset>
<frame name="topFrame" rows="160,*">
<frameset>
<frame name="leftFrame">
<frame name="rightFrame">
</frameset>
</frameset>
以上代码,我们有三个frame框架。分为上,左、右。获取上面的框架
我们可以使用window.frames[0]、window.frames['topFrame']来获取 。或者可以使用top来获取top.frames[0]
2.1.3 窗口位置
用来确定和修改window对象位置的属性和方法有很多,
IE、Safari、Opera、Chrome都提供了screenLeft、screenTop属性,分别表示窗口距离屏幕左边,窗口距离屏幕上边的距离。
Firefox使用screenX、screenY表示。
Safari、Chrome同时支持两个属性。
这种情况,各个浏览器都有自己的支持属性,如果想兼容各个浏览器,我们应该怎么办呢?
这时候就需要很好的利用三目运算了。利用三目运算符判断浏览器是否支持对应的属性。
三目运算符 表达式?true:false;
typeof(window.screenTop)=='number'?window.screenTop:window.screenY。
这样,支持screenTop的浏览器就会返回window.screenTop,不支持的浏览器就会返回screenY.
2.1.4 窗口大小
IE9+、Firefox、Safari、Opera、Chrome有四个属性:innerWidth、innerHeight、outerWidth、outerHeight
IE9+、Firefox、Safari:outerWidth,outerHeight返回的是浏览器窗口本身的大小
即:以屏幕分辨率为1920的电脑为例
console.log(window.outerWidth) 输出一直都是1920
window.innerWidth 会根据你调节窗口的在大小而改变。
Opera:这两个属性表示的是单个标签页对应的浏览器窗口的大小。而innerWidth、innerHeight则表示容器中页面视图区的大小(不包括边框宽度)
Chrome:outerWidth、outerHeight与innerWidth、innerHeight返回相同的值,即视口大小,而非浏览器窗口大小。
知识点:
在IE8及更早的版本里,并没有提供取得当前浏览器窗口尺寸的属性。但是它可以通过DOM获取页面可视区域的相关信息。
IE、Firefox、Safari、Opera、Chrome中,
document.documentElement.clientWidth
document.documentElement.clientHeight保存了页面视口的信息。
在IE6中,以上的两个属性在标准的模式下才有效;
如果在混杂模式下就必须通过
document.body.clientWidth和document.body.clientHeight获取相同的信息
2.1.5 导航和打开窗口
这里主要应用的是window.open()方法
首先我们来看一下它的语法
window.open(URL,name,specs,replace)
URL:打开页面的URL
name:指定target属性或者窗口的名称
specs:一个特性字符串。用来设置窗口的属性,并以逗号隔开。
replace:规定了装载到窗口的URL是在窗口浏览历史中添加一个新条目,还是替换浏览历史中的当前条目。
例:
window.open("https://www.baidu.com/", "selfWindow", "width:400,height:400")
这样,就在页面的右下角打开了一个400*400的新窗口
知识点:
出于安全的考虑,很多浏览器在弹出窗口配置方面作了很多限制。例如,大多数的浏览器都内置了屏蔽程序,屏蔽弹出窗口。
如果浏览器屏蔽了弹出窗口,window.open()会抛出一个错误。基于此
1、检测浏览器是否屏蔽了弹出窗口,检测window.open()的返回值,并将它的调用放入到try catch中
var blocked = false;
try{
var wroxWin = window.open("https://www.baidu.com/", "selfWindow")
if (wroxWin == null){
blocked = true;
}
}catch(error){
blocked = true;
}
if(blocked){
alert('弹出窗口被屏蔽')
}
2、对于没有屏蔽弹出窗口的浏览器,可以安装 Yahoo,Toolbar等带有内置屏蔽程序的实用工具。
2.1.6 间歇调用和超时调用
名字听起来很晦涩难懂,但其实这一块主要运用的是
window的setTimeout及setInterval方法
名词解释:
间歇调用:是指程序每隔一断时间就执行一次
超时调用:指程序在指定的时间过后,执行一次
根据以上的名词解释,便可以得知,间歇调用也就是setInterval,超时调用指setTimeout方法。
两个方法用法相同,此处我们就不再过多介绍。
2.1.7 系统对话框
所谓系统对话框,也就是系统内置的对话框方法。
常用的alert、comfirm、prompt
三者具体的使用方式
三个都是弹出一个对话框,不同的是他们与用户的交互程度会依次(从左到右)递增
alert:只是一个对话框。只有一个关闭按钮('关闭对话框')
comfirm:比alert更功能丰富一点,多了一个选择的。
prompt:在comfirm的基础上,还添加了一个文本框,可以输入内容。
点击确定后,会返回文本框中的值。
点击取消会返回null
系统对话框有以下几个特点
1、样式由系统决定
这些是由系统内置的对话框,不存在于html中,它的样式也不由css来决定。而是由浏览器决定。浏览器内置什么样子,展示出来便是什么样子。所以每个浏览器的对话框各不相同
2、调用系统对话框时,代码会结束运行
当程序在运行过程中,遇到系统对话框,如alert,系统会暂停运行程序。直到对话框关闭,程序再继续运行。
2.2 Location
location是最有用的BOM对象之一。它提供了与当前窗口中加载的文档有关的信息。
它也是一个非常特别的属性。因为,它即是window的属性,也是document的属性。即
window.location == document.location
我们通常用它来访问地址栏的信息,如
方法名 | 返回值 | 说明 |
---|---|---|
hash | #name=test | 返回地址栏中#后面的信息 |
host | baidu.com:80 | 服务器名及端口号 |
search | ?name=a | 返回地址中查询字符串。字符串以?开头 |
href | https://baidu.com?name=test | 返回当前地址栏中完整的URL地址 |
2.2.1 查询字符串参数
以上表中所列的location的一些方法,我们可以获取出大部分的地址栏 信息。但大部分都是完整的。如果我们想获取单个的变量。
例如:想要获取地址栏中name的参数及参数值,我们又该怎么做呢?
这时候,我们可以将从地址栏 获取的信息,整合到一起,并转换成一个对象,这样,我们需要的参数就变成了对象的一个属性。
function getStringArgs(){
var locationURL = (location.search.length>0?location.search.substring(1):"")//获取查询字符串,如果有值,则返回?之后的内容,没有值则返回空串
args = {};
items = locationURL.length?locationURL.split("&"):[];
name = null;
value = null;
len = items.length;
for(let i=0;i<len;i++){
item = items[i].split("=")
name = decodeURIComponent(item[0]);
value =decodeURIComponent(item[1]);
args[name] = value;
}
return args;
}
知识点:
1、decodeURIComponent用于解码。一般用于获取中文情况。因为中文在地址栏中会被编码,所以,我们获取值时,应该先进行解码。
2.2.2 位置操作
我们也可以通过location改变浏览器的位置
最常见的
window.location.href = "http://baidu.com"
我们便可以由当前的页面,跳转到百度页
localtion中还有一个assign方法
location.assign("http://baidu.com")
同样能达到跳转页面的效果
我们可以通过修改location的值,达到刷新当前页面,或者跳转其它页面的效果。如下图
图片截自JavaScript高级程序设计(第三版)
知识点:
1、修改location的值,除了修改hash外,页面都会重新加载
2、通过location修改地址后,浏览器会在历史记录里添加一条访问记录。这也意味着,我们可以通过“后退”“前进”按钮导航到前一个/后一个页面
2.3 Navigator对象
做为一个前端er,我们都知道navigator可以获取客户端浏览器信息。
每个浏览器都有自己的获取浏览器信息的方式,比如
IE中的window.clientInformation
Opera中的window.Opera
但是navigator是每个支持JavaScript中共有的对象,下面表中,列出了存在所有浏览器的属性或方法,以及它支持的浏览器版本
图片截自《JavaScript高级程序设计》(第三版)
这些属性通常用于检测浏览器的类型
2.3.1 检测是否安装插件
我们可以通过navigator对象,检测浏览器是否安装了某个插件。对于非IE浏览器来说,我们可以通过plugins数组进行检测
以下是小落落在谷歌做的测试
非IE浏览器检测
window.navigator.plugins返回的是安装插件数组。每个数组项都是对安装插件的一个信息描述,如:
name:插件名
filename:插件的文件名
description:插件的描述等等...
如果我们想自己写函数,判断是否安装某个插件时,我们需要注意
要将传入的插件名,与navigator对象的插件名统一化(统一成大写或小写),避免出现大小写不一致的情况。
知识点:
plugins属性中有一个refresh方法,它可以接受一个布尔值
这个方法的作用,是刷新插件库,以返回最新安装的插件,接收的参数是判断是否要刷新浏览器页面
参数为true时,刷新插件库的同时,刷新包含插件的所有页面
为false时,只刷新插件库,不刷新页面
IE浏览器检测
在IE中检测插件唯一的方法,是使用专用的ActiveXObject类型,IE是以COM对象来实现插件的,而COM有唯一的标识符来标识。所以,如果我们想知道IE浏览器中的插件,我们需要知道他的唯一标识符
2.4 screen对象
恩~ 这个对象,在编程中用处不大,screen基本上用来表示客户端的显示能力,如屏幕的像素宽度,它的属性大部分都是只读的
图片截自《JavaScript高级程序设计》(第三版)
2.5 History对象
History对象中保存了用户的操作信息,从窗口被打开开始算起。
出于安全考虑,开发人员不能得知用户访问过的具体地址,但是可以通过history的访问列表,完成前进、后退的功能。
下面我们简单介绍几种常用的
go()
可以随意在用户的历史记录中跳转
history.go(-1) 后退一页
history.go(1) 前进一页
history.go(2) 前进两页
也可以向go传递字符串
history.go('baidu') 跳转到用户访问过的包含baidu的链接
forward() 前进一页
back() 后退一页
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。