关于BOM浏览器文档对象模型

前言

这两天小落落读《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修改地址后,浏览器会在历史记录里添加一条访问记录。这也意味着,我们可以通过“后退”“前进”按钮导航到前一个/后一个页面

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章