BOM之window 对象

8.1 window 对象

在网页中定义的任何一个对象、变量和函数,都以 window 作为其 Global 对象,因此有权访问parseInt()等方法

8.1.1 全局作用域

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

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

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

尝试访问未声明的变量会抛出错误,但是通过查询 window 对象,可以知
道某个可能未声明的变量是否存在。例如:

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

Windows Mobile 平台的 IE 浏览器不允许通过 window.property = value 之类的形式,直接在 window 对象上创建新的属性或方法。可是,在全局作用域中声明的所有变量和函数,照样会变成 window 对象的成员。

8.1.2 窗口关系及框架

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

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

以上代码创建了一个框架集,其中一个框架居上,两个框架居下。对这个例子而言,可以通过window.frames[0]或者 window.frames[“topFrame”]来引用上方的框架。不过,恐怕你最好使用top 而非 window 来引用这些框架(例如,通过 top.frames[0])。
我们知道, top 对象始终指向最高(最外)层的框架,也就是浏览器窗口。使用它可以确保在一个框架中正确地访问另一个框架。

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

除非最高层窗口是通过 window.open()打开的(本章后面将会讨论),否则其 window 对象的 name 属性不会包含任何值。

在使用框架的情况下,浏览器中会存在多个 Global 对象。在每个框架中定义的全局变量会自动成为框架中 window 对象的属性。由于每个 window 对象都包含原生类型的构造函数,因此每个框架都有一套自己的构造函数,这些构造函数一一对应,但并不相等。例如, top.Object 并不等于 top.frames[0].Object。这个问题会影响到对跨框架传递的对象使用 instanceof 操作符。

8.1.3 窗口位置

IE、 Safari、 Opera 和 Chrome 都提供了screenLeftscreenTop 属性,分别用于表示窗口相对于屏幕左边和上边的位置。 Firefox 则在screenXscreenY 属性中提供相同的窗口位置信息, Safari 和 Chrome 也同时支持这两个属性。 Opera虽然也支持 screenX 和 screenY 属性,但与 screenLeft 和 screenTop 属性并不对应,因此建议大家不要在 Opera 中使用它们。使用下列代码可以跨浏览器取得窗口左边和上边的位置。

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 的值。在使用这些值的过程中,还必须注意一些小问题。在 IE、 Opera 中, screenLeft 和 screenTop 中保存的是从屏幕左边和上边到由 window 对象表示的页面可见区域的距离。换句话说,如果 window 对象是最外层对象,而且浏览器窗口紧贴屏幕最上端——即 y 轴坐标为 0,那么 screenTop 的值就是位于页面可见区域上方的浏览器工具栏的像素高度。但是,在 Chrome、 Firefox 和 Safari 中, screenY 或 screenTop中保存的是整个浏览器窗口相对于屏幕的坐标值,即在窗口的 y 轴坐标为 0 时返回 0。

更让人捉摸不透是, Firefox、 Safari 和 Chrome 始终返回页面中每个框架的 top.screenX 和top.screenY 值。即使在页面由于被设置了外边距而发生偏移的情况下,相对于 window 对象使用screenX 和 screenY 每次也都会返回相同的值。而 IE 和 Opera 则会给出框架相对于屏幕边界的精确坐
标值。

使用 moveTo()和 moveBy()方法倒是有可能将窗口精确地移动到一个新位置。

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

8.1.4 窗口大小

IE9+、 Firefox、 Safari、 Opera 和 Chrome 均为此提供了 4 个属性: innerWidth、 innerHeight、 outerWidth 和 outerHeight

  • 在 IE9+、 Safari 和 Firefox中, outerWidthouterHeight 返回浏览器窗口本身的尺寸(无论是从最外层的 window 对象还是从某个框架访问)。
  • 在 Opera 中,这两个属性的值表示页面视图容器( Opera 中单个标签页对应的浏览器窗口)的大小。而 innerWidth 和 innerHeight则表示该容器中页面视图区的大小(减去边框宽度)。
  • 在 Chrome 中, outerWidth、 outerHeight 与innerWidth、 innerHeight 返回相同的值,即视口(viewport)大小而非浏览器窗口大小。

在 IE、Firefox、Safari、Opera 和 Chrome 中, document.documentElement.clientWidth
document.documentElement.clientHeight 中保存了页面视口的信息。在 IE6 中,这些属性必须在标准模式下才有效;如果是混杂模式,就必须通过 document.body.clientWidth 和 document.body.clientHeight 取得相同信息。而对于混杂模式下的Chrome,则无论通过 document.documentElement 还是 document.body 中的 clientWidth 和 clientHeight 属性,都可以取得视口的大小。
虽然最终无法确定浏览器窗口本身的大小,但却可以取得页面视口的大小,如下所示。

var pageWidth = window.innerWidth,
pageHeight = window.innerHeight;
if (typeof pageWidth != "number"){
	if (document.compatMode == "CSS1Compat"){
		pageWidth = document.documentElement.clientWidth;
		pageHeight = document.documentElement.clientHeight;
	} else {
		pageWidth = document.body.clientWidth;
		pageHeight = document.body.clientHeight;
	}
}

对于移动设备, window.innerWidth 和 window.innerHeight 保存着可见视口,也就是屏幕上可见页面区域的大小。移动 IE 浏览器不支持这些属性,但通过 document.documentElement.clientWidth 和 document.documentElement.clientHeihgt 提供了相同的信息。随着页面的缩放,这些值也会相应变化。

在其他移动浏览器中, document.documentElement 度量的是布局视口,即渲染后页面的实际大小(与可见视口不同,可见视口只是整个页面中的一小部分)。移动 IE 浏览器把布局视口的信息保存在document.body.clientWidth 和document.body.clientHeight 中。这些值不会随着页面缩放变化。

使用 resizeTo()和 resizeBy()方法可以调整浏览器窗口的大小。

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

8.1.5 导航和打开窗口

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

//等同于< a href="http://www.wrox.com" target="topFrame"></a>
window.open("http://www.wrox.com/", "topFrame");

如果有一个名叫"topFrame"的窗口或者框架,就会在该窗口或框架加载这个 URL;否则,就会创建一个新窗口并将其命名为"topFrame"。此外,第二个参数也可以是下列任何一个特殊的窗口名称: _self、 _parent、 _top 或_blank。

1. 弹出窗口

如果给 window.open()传递的第二个参数并不是一个已经存在的窗口或框架,那么该方法就会根据在第三个参数位置上传入的字符串创建一个新窗口或新标签页。如果没有传入第三个参数,那么就会打开一个带有全部默认设置(工具栏、地址栏和状态栏等)的新浏览器窗口(或者打开一个新标签页——根据浏览器设置)。在不打开新窗口的情况下,会忽略第三个参数。
在这里插入图片描述
表中所列的部分或全部设置选项,都可以通过逗号分隔的名值对列表来指定。

var wroxWin = window.open("http://www.wrox.com/","wroxWindow",
"height=400,width=400,top=10,left=10,resizable=yes");
//调整大小
wroxWin.resizeTo(500,500);
//移动位置
wroxWin.moveTo(100,100);
调用 close()方法还可以关闭新打开的窗口。
wroxWin.close();
alert(wroxWin.closed); //true
wroxWin.opener = null;

将 opener 属性设置为 null 就是告诉浏览器新创建的标签页不需要与打开它的标签页通信,因此可以在独立的进程中运行。标签页之间的联系一旦切断,将没有办法恢复。

2. 安全限制

Windows XP SP2 中的 IE6 对弹出窗口施加了多方面的安全限制,包括不允许在屏幕之外创建弹出窗口、不允许将弹出窗口移动到屏幕以外、不允许关闭状态栏等。 IE7 则增加了更多的安全限制,如不允许关闭地址栏、默认情况下不允许移动弹出窗口或调整其大小。 Firefox 1 从一开始就不支持修改状态栏,因此无论给 window.open()传入什么样的特性字符串,弹出窗口中都会无一例外地显示状态栏。后来的 Firefox 3 又强制始终在弹出窗口中显示地址栏。 Opera 只会在主浏览器窗口中打开弹出窗口,但不允许它们出现在可能与系统对话框混淆的地方。

此外,有的浏览器只根据用户操作来创建弹出窗口。这样一来,在页面尚未加载完成时调用window.open()的语句根本不会执行,而且还可能会将错误消息显示给用户。换句话说,只能通过单击或者击键来打开弹出窗口。

对于那些不是用户有意打开的弹出窗口, Chrome 采取了不同的处理方式。它不会像其他浏览器那样简单地屏蔽这些弹出窗口,而是只显示它们的标题栏,并把它们放在浏览器窗口的右下角

3. 弹出窗口屏蔽程序

如果是浏览器内置的屏蔽程序阻止的弹出窗口,那么 window.open()很可能会返回 null。
如果是浏览器扩展或其他程序阻止的弹出窗口,那么 window.open()通常会抛出一个错误。因此,要想准确地检测出弹出窗口是否被屏蔽,必须在检测返回值的同时,将对 window.open()的调用封装.在一个 try-catch 块中,如下所示。

var blocked = false;
try {
	var wroxWin = window.open("http://www.wrox.com", "_blank");
	if (wroxWin == null){
		blocked = true;
	}
} catch (ex){
	blocked = true;
}
if (blocked){
	alert("The popup was blocked!");
}

检测弹出窗口是否被屏蔽只是一方面,它并不会阻止浏览器显示与被屏蔽的弹出窗口有关的消息。

8.1.6 间歇调用和超时调用

1. 超时调用

超时调用需要使用 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);

超时调用的代码都是在全局作用域中执行的,因此函数中 this 的值在非严格模
式下指向 window 对象,在严格模式下是 undefined

2. 间歇调用setInterval()
//不建议传递字符串!
setInterval ("alert('Hello world!') ", 10000);
//推荐的调用方式
setInterval (function() {
	alert("Hello world!");
}, 10000);

调用 setInterval()方法同样也会返回一个间歇调用 ID,该 ID 可用于在将来某个时刻取消间歇调用。要取消尚未执行的间歇调用,可以使用 clearInterval()方法并传入相应的间歇调用 ID。取消间歇调用的重要性要远远高于取消超时调用,因为在不加干涉的情况下,间歇调用将会一直执行到页面卸载。

var num = 0;
var max = 10;
var intervalId = null;
function incrementNumber() {
	num++;
	//如果执行次数达到了 max 设定的值,则取消后续尚未执行的调用
	if (num == max) {
		clearInterval(intervalId);
		alert("Done");
	}
}
intervalId = setInterval(incrementNumber, 500);
IntervalExample02.

一般认为,使用超时调用来模拟间歇调用的是一种最佳模式。在开发环境下,很少使用真正的间歇调用,原因是后一个间歇调用可能会在前一个间歇调用结束之前启动。

var num = 0;
var max = 10;
function incrementNumber() {
	num++;
	//如果执行次数未达到 max 设定的值,则设置另一次超时调用
	if (num < max) {
		setTimeout(incrementNumber, 500);
	} else {
		alert("Done");
	}
}
setTimeout(incrementNumber, 500);

8.1.7 系统对话框

浏览器通过 alert()、 **confirm() prompt()**方法可以调用系统对话框向用户显示消息。系统对话框与在浏览器中显示的网页没有关系,也不包含 HTML。它们的外观由操作系统及(或)浏览器设置决定,而不是由 CSS 决定。此外,通过这几个方法打开的对话框都是同步和模态的。也就是说,显示这些对话框的时候代码会停止执行,而关掉这些对话框后代码又会恢复执行。

1. alert()
2. confirm()
if (confirm("Are you sure?")) {
	alert("I'm so glad you're sure! ");
} else {
	alert("I'm sorry to hear you're not sure. ");
}
3.prompt()
var result = prompt("What is your name? ", "文本输入域的默认值");
if (result !== null) {
	alert("Welcome, " + result);
}

Google Chrome 浏览器还引入了一种新特性。如果当前脚本在执行过程中会打开两个或多个对话框,那么从第二个对话框开始,每个对话框中都会显示一个复选框,以便用户阻止后续的对话框显示,除非用户刷新页面。
还有两个可以通过 JavaScript 打开的对话框,即“查找”和“打印”。这两个对话框都是异步显示的,能够将控制权立即交还给脚本。这两个对话框与用户通过浏览器菜单的“查找”和“打印”命令打开的对话框相同。而在 JavaScript 中则可以像下面这样通过 window 对象的 find()和 print()方法打开它们。

//显示“打印”对话框
window.print();
//显示“查找”对话框
window.find();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值