2

前言

这两天小落落读《JavaScrpit高级程序设计》(第三版)依然读到了很多的知识盲点,以此篇作一个记录。如有错误也希望大家指正。

BOM对象是什么

BOM(Browser Object Model 浏览器对象模型)
BOM提供了很多对象,用来访问浏览器的功能,而这些功能与任何的网页内容无关。

EcmaScript的核心 是JavaScript,而BOM无疑是JavaScript的核心。

BOM对象上的属性

我们先以一张图来表示BOM对象上的属性。

BOM.png
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删除。
image.png

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的setTimeoutsetInterval方法

名词解释:
间歇调用:是指程序每隔一断时间就执行一次
超时调用:指程序在指定的时间过后,执行一次

根据以上的名词解释,便可以得知,间歇调用也就是setInterval,超时调用指setTimeout方法。

两个方法用法相同,此处我们就不再过多介绍。

2.1.7 系统对话框

所谓系统对话框,也就是系统内置的对话框方法。

常用的alert、comfirm、prompt
三者具体的使用方式
三个都是弹出一个对话框,不同的是他们与用户的交互程度会依次(从左到右)递增

alert:只是一个对话框。只有一个关闭按钮('关闭对话框')
image.png

comfirm:比alert更功能丰富一点,多了一个选择的。
image.png

prompt:在comfirm的基础上,还添加了一个文本框,可以输入内容。
image.png
点击确定后,会返回文本框中的值。
点击取消会返回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的值,达到刷新当前页面,或者跳转其它页面的效果。如下图
image.png
图片截自JavaScript高级程序设计(第三版)

知识点:
1、修改location的值,除了修改hash外,页面都会重新加载

2、通过location修改地址后,浏览器会在历史记录里添加一条访问记录。这也意味着,我们可以通过“后退”“前进”按钮导航到前一个/后一个页面

2.3 Navigator对象

做为一个前端er,我们都知道navigator可以获取客户端浏览器信息。
每个浏览器都有自己的获取浏览器信息的方式,比如
IE中的window.clientInformation
Opera中的window.Opera

但是navigator是每个支持JavaScript中共有的对象,下面表中,列出了存在所有浏览器的属性或方法,以及它支持的浏览器版本
image.png
图片截自《JavaScript高级程序设计》(第三版)
这些属性通常用于检测浏览器的类型

2.3.1 检测是否安装插件

我们可以通过navigator对象,检测浏览器是否安装了某个插件。对于非IE浏览器来说,我们可以通过plugins数组进行检测
以下是小落落在谷歌做的测试
image.png

非IE浏览器检测
window.navigator.plugins返回的是安装插件数组。每个数组项都是对安装插件的一个信息描述,如:
name:插件名
filename:插件的文件名
description:插件的描述等等...

如果我们想自己写函数,判断是否安装某个插件时,我们需要注意
要将传入的插件名,与navigator对象的插件名统一化(统一成大写或小写),避免出现大小写不一致的情况。

知识点:

plugins属性中有一个refresh方法,它可以接受一个布尔值
这个方法的作用,是刷新插件库,以返回最新安装的插件,接收的参数是判断是否要刷新浏览器页面
参数为true时,刷新插件库的同时,刷新包含插件的所有页面
为false时,只刷新插件库,不刷新页面

IE浏览器检测

在IE中检测插件唯一的方法,是使用专用的ActiveXObject类型,IE是以COM对象来实现插件的,而COM有唯一的标识符来标识。所以,如果我们想知道IE浏览器中的插件,我们需要知道他的唯一标识符

2.4 screen对象

恩~ 这个对象,在编程中用处不大,screen基本上用来表示客户端的显示能力,如屏幕的像素宽度,它的属性大部分都是只读的

微信图片_20191015180410.png

图片截自《JavaScript高级程序设计》(第三版)

2.5 History对象

History对象中保存了用户的操作信息,从窗口被打开开始算起。
出于安全考虑,开发人员不能得知用户访问过的具体地址,但是可以通过history的访问列表,完成前进、后退的功能。

下面我们简单介绍几种常用的

go()
可以随意在用户的历史记录中跳转
history.go(-1)  后退一页
history.go(1)   前进一页
history.go(2)   前进两页

也可以向go传递字符串
history.go('baidu')  跳转到用户访问过的包含baidu的链接 

forward()   前进一页
back()      ​后退一页


麦篱落
146 声望4 粉丝