Javascript-BOM(浏览器对象模型)

1、window对象

BOM对象的核心对象是window,它表示游览器的一个实例。在游览器中,window对象有双重角色,它既是通过Javascript访问游览器窗口的一个接口,又是ECMAScript规定的Global对象。这意味着在网页中定义的任何一个对象、变量和函数,都以window对象作为其Global对象,因此有权访问parseInt()等方法。

1.1、全局作用域

所有在全局作用域中声明的变量、函数都会变成window对象的属性和方法。例:

var age = 29;
function sayAge() {
	alert(this.age);
}

alert(window.age);    //29
sayAge();             //29
window.sayAge();      //29

我们在全局作用域中定义了一个变量age和一个函数sayAge(),它们被自动归在了window对象名下。于是,可以通过window.age访问变量age,可以通过window.sayAge()访问函数sayAge()。由于sayAge()存在于全局作用域中,因此this.age被映射到window.age,最终显示的仍然是正确的结果。

抛开全局变量会成为window对象的属性不谈,定义全局变量与在window对象上直接定义属性还是有一点儿区别的:全局变量不能通过delete操作符删除,而直接在window对象上定义的属性可以:

var age = 29;
window.color = "red";
// 在IE < 9 时抛出错误,在其他所有浏览器中都返回false
delete window.age;

// 在IE < 9 时抛出错误,在其他所有浏览器中都返回true
delete window.color;   // return true

alert(window.age);     // 29
alert(window.color);   // underfined

刚才使用var语句添加的window对象有一个名为[Configurable]的特性,这个特性的值被设置为false,因此这样定义的属性不可以通过delete操作符删除。IE8以及更早版本在遇到delete删除window对象的属性是,不管该属性最初是如何创建的,都会抛出错误,以示警告。IE9及更高版本不会抛出错误。

另外,还要记住一件事:尝试访问为声明的变量会抛出错误,但是通过查询window对象,可以知道某个可能为声明的变量是否存在:

// 这里会抛出错误,因为oldValue未定义
var newValue = oldValue;
// 这里不会抛出错误,因为这是一次属性查询
var newValue = window.oldValue;

很多的全局Javascript对象(如location和navigator)实际都是window对象的属性。

1.2、窗口关系及框架

如果页面中包含框架,则每个框架中都拥有自己的window对象,并且保存在frames集合中。在frames集合中,可以通过树枝索引(从0开始,从左到右,从上到下)或者框架的名称来访问相应的window对象。每个window对象都有一个name 属性,其中包含框架的名称。

<html>
    <head>
        <title>Frameset Example</title>
    </head>
    <frameset rows="160,*">
        <frame src="frame.html" name="topFrame"></frame>
        <frameset cols="50%,50%">
            <frame src="anotherframe.html" name="leftFrame"></frame>
            <frame src="yetanotherframe.html" name="rightFrame"></frame>
        </frameset>
    </frameset>
</html>

我们知道,top对象始终指向最高(最外)层的框架,也就是浏览器窗口。使用它可以保证在一个框架中正确的访问另一个框架。因为对于在一个框架中编写的任何代码,其中的window对象指向的都是那个框架的对象的实例,而非最高层的框架。下图展示了在最高层窗口中,通过代码来访问前面例子中每个框架的不同方式:

 

 

与top相对应的另一个window对象是parent。顾名思义,parent(父)对象始终指向当前框架的直接上层框架。在某些情况下,parent有可能等于top;但是在没有框架的情况下,parent一定等于top(此时它们都等于window)。例:

<html>
    <head>
        <title>Frameset Example</title>
    </head>
    <frameset rows="100,*">
        <frame src="frame.html" name="topFrame"></frame>
        <frameset cols="50%,50%">
            <frame src="anotherframe.html" name="leftFrame"></frame>
            <frame src="anotherframeset.html" name="rightFrame"></frame>
        </frameset>
    </frameset>
</html>

这个框架中包含了另一个框架:

<html>
    <head>
        <title>Frameset Example</title>
    </head>
    <frameset rows="100,*">
        <frameset cols="50%,50%">
            <frame src="red.html" name="redFrame"></frame>
            <frame src="blue.html" name="blueFrame"></frame>
        </frameset>
    </frameset>
</html>

 

浏览器在加载完第一个框架集后,会继续将第二个框架集加载到rightFrame中。如果代码位于redFrame(或blueFrame)中,那么parent对象指向的就是rightFrame。可是,如果代码位于topFrame中,则parent指向的是top,因为topFrame的直接上层框架就是最外层框架。上图展示了不同window对象的值。

注意除非最高层窗口是通过window.open()打开的,否则其window对象的name属性不会包含任何值。与框架有关的最后一个对象是self。他始终指向window。实际上,self和window对象可以相互使用。引入self对象的目的是为了和top和parent对象对应起来,因此它不格外包含其它值。所有这些对象都是window对象的属性,可以通过window.parent、window.top等形式来访问。同时,这也意味着可以将不同层次的window对象连缀起来,

例如: window.parent.parent.frames[0]

使用框架集的情况下,浏览器中会存在多个Global对象。在每个框架中定义的全局变量会自动成为框架中的window对象的属性。由于每个window对象都包含原生类型的构造函数,因此每个框架都有一套自己的构造函数,这些构造函数一一对应,但并不相等。

例如: top.Object并不等于top.frames[0].Object。这个问题会影响到对跨框架传递的对象使用instanceof操作符。

1.3、窗口位置

用来确定和修改window对象位置的属性和方法很多IE,Safari,Opera和Chrome都提供了screenLeft和screenTop属性,分别用于表示窗口相对于屏幕左边和上边的位置。Firefox则在screenX和screenY属性中提供相同的窗口位置信息,Safari和Chrome也同时支持这两个属性。

例如:

var leftPos = (typeof window.screenLeft == 'number') ? window.screenLeft : window.screenX;
var topPos  = (typeof window.screenTop == 'number') ? window.screenTop : window.screenY;

这个例子运用二元运算符确定screenLeft和screenTop属性是否存在,如果是(IE,Safari,Opera,Chrome)则取得这两个属性的值,如果不存在(Firefox),则取得screenX和screenY的值。

使用moveTo()和moveBy()方法可以将窗口精确的移动到一个新位置。moveTo()接收的是新位置的X和Y坐标,moveBy()接收的是在水平和垂直方向上移动的像素数。

//将窗口移动到屏幕左上角
window.moveTo(0,0);
//将窗口向下移动100像素
window.moveBy(0,100);
//将窗口移动到(200,300)
window.moveTo(200,300);
//将窗口向左移动50像素
window.moveBy(-50,0);

这两个方法都可能被浏览器禁用,而且这两个方法都不适用于框架,而只能对最外层的window对象使用。

1.4、窗口大小

跨浏览器确定一个窗口的大小,IE9+、Firefox、Safari、Opera和Chrome均为此提供了四个属性:innerWidth,innerHeight,outerWidth,outerHeight。在IE9+、Safari、Firefox中outerWidth和outerHeight返回浏览器窗口本身的尺寸(无论是从最外层的window对象还是从某个框架访问),在Opera中,这两个属性的值表示页面视图容器的大小。而innerWidth和innerHeight则表示该容器中页面视图区的大小(减去边框宽度)。在Chrome中,outerWidth、outerHeight和innerWidht、innerHeight返回一样的值,即视图大小而非浏览器窗口的大小。在IE9、Firefox、Safari、Opera和Chrome中,document.documentElement.clientWidth和document.documentElement.clientHeight中保存了页面视图的信息。

使用resizeTo()和resizeBy()方法可以调整浏览器窗口的大小。这两个方法都接收两个参数,其中risezeTo()接收浏览器窗口的新宽度和新高度,resizeBy()接收新窗口的宽度和高度之差。例如:

// 调整到100 * 100
window.resizeTo(100,100);
// 调整到200 * 150
window.resizeBy(200,150);
// 调整到 300 * 300
window.resizeTo(300,300);

这两个方法也有可能被禁用,而且,这两个方法不适用于框架,而只能对最外层的window对象使用。

1.5、导航和打开窗口

使用window.open()方法既可以导航到一个特定的URL,也可以打开一个新的浏览器窗口。这个方法可以接收四个参数:要加载的URL,窗口目标,一个特性字符串和一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值。通常只传递第一个参数,最后一个参数只在不打开新窗口的情况下使用。如果为window.open()传递了第二个参数,而且该参数是已有窗口或框架的名称,那么就会在具有该名称的窗口或框架中加载第一个参数制定的URL。

// 等同于<a href='http://www.w3school.com.cn/js/js_window.asp' target='topFrame'></a>
window.open('http://www.w3school.com.cn/js/js_window.asp','topFrame');

调用这行代码,如果有个名叫‘topFrame’的窗口或框架,就会在该窗口或者框架中加载这个URL,否则,就会创建一个新窗口,并将其命名为‘topFrame’。第二个参数还可以是下列任何一个特殊的窗口名称:_self,_parent,_top和_blank。

弹出窗口

如果给window.open()传递的第二个参数不是一个已经存在的窗口或框架,那么该方法就会根据在第三个参数位置上传入的字符串创建一个新窗口或新标签页。如果没有传入第三个参数,就会打开一个带有全部默认设置(工具栏、地址栏、状态栏)的新浏览器窗口(或者打开一个新标签页)在不打开新窗口的情况下,会忽略第三个参数。

第三个参数是一个逗号分割的设置字符串,表示在新窗口中都有那些特性:

设置 说明
fullscreen
height
left
location
menubar
resizable
scrollbars
status
toolbar
top
width
yes or no
数值
数值
yes or no
yes or no
yes or no
yes or no
yes or no
yes or no
数值
数值
表示浏览器窗口是否最大化(仅限IE)
表示新窗口的高度
表示新窗口的左坐标
表示是否在浏览器窗口中显示地址栏。不同浏览器默认值不同。如果设置为no,地址栏可能被隐藏也可能被禁用
表示是否在浏览器窗口中显示菜单栏
表示是否可以通过拖动浏览器的边框改变浏览器的大小
表示如果内容在视图中显示不下,是否允许滚动
表示是否在浏览器窗口中显示状态栏
表示是否在浏览器窗口中显示工具栏
表示新窗口的上坐标
表示新窗口的宽度
window.open('http://www.w3school.com.cn/js/js_window.asp','w3school','height=300,width=400,top=10,resizable=yes');

window.open()方法会返回一个指向新窗口的引用。引用的对象和其他window对象大致相似,但我们可以对其进行更多控制。

1.6、间歇调用和超时调用

  Javascript是单线程语言,但它允许通过设置超时和间歇时间值来调度代码在特定的时刻执行。前者是在指定的时间之后执行,后者则是每隔制定的时间就执行执行一次代码。

  超时调用需要用到window对象的setTimeout()方法,它接收两个参数:要执行的代码和以毫秒表示的时间(在指定的时间以后执行)。其中,第一个参数可以是一个包含Javascript代码的字符串(就和在eval()函数中使用的字符串一样),也可以是一个函数。例如,下面对setTimeout()的两次调用都会在一秒钟后显示一个警告框。

//不推荐传递字符串
setTimeout("alert('Hello World!')",1000);
//推荐的调用方式
setTimeout(function(){
    alert('Hello World!');
},1000)

  虽然这两种方式都没有问题,但是因为传递字符串可能会造成性能损失,所以不建议以字符串作为第一个参数。

  第二个参数是一个表示等待多长时间的毫秒数,但经过该时间后,制定的代码不一定执行。Javascript是一个单线程的解释器,因此一段时间内只能执行一段代码。为了控制要执行的代码的,就要有一个Javascript队列。这些任务会按照将它们添加到队列的顺序执行。setTimeout()第二个参数告诉Javascript再经过多长时间把当前的任务添加到队列中。如果队列是空的,那么添加的代码会立即执行;如果队列不是空的,那么它要等前面的代码执行完了以后再执行。

调用setTimeout()之后,那么该方法返回一个ID,表示超时调用。这个超时调用ID是计划执行代码的唯一标示符,可以通过它来取消超时调用。要取消尚未执行的超时调用计划,可以调用clearTimeout()方法并将相应的超时ID作为参数传递给它:

 var timeoutId = setTimeout(function(){
            alert('Hello World!');
        },1000);

    clearTimeout(timeoutId);

  间接调用与超时调用类似,只不过它会按照制定的时间间隔重复执行代码。直至间隔调用被取消或页面被卸载。设置间接调用的方法是setInterval(),它接收的参数和setTimeout()相同。要取消可以使用clearInterval()方法。

1.7、系统对话框

  浏览器通过alert(),confirm()和prompt()方法可以调用系统对话框向用户显示消息。系统对话框与在网页中显示的内容没有关系,也不包含HTML。它们的外观由操作系统和浏览器设置决定,和CSS无关。

  alert()生成的警告对话框向用户显示一些它们无法控制的信息,例如:错误信息等。用户只能在看完信息后关闭对话框。
  confirm()对话框会产生两个按钮‘确定’和‘取消’,可以检查confirm()的返回值:true表示单机OK,false表示单机Cancel或者是关闭。
  prompt()对话框产生一个‘提示’框。用于用户输入一些文本,提示框中除了‘确定’‘取消’,还多了一个文本框,供用户输入。prompt()方法接收两个参数:要显示给用户的文本提示和文本输入域的默认值。如果用户单机了OK按钮,则返回文本输入域中的值,如果用户单机了Cancel或者是关闭了对话框,则返回null。

posted @ 2014-06-22 17:25  huangt  阅读(340)  评论(0编辑  收藏  举报