8. windows 对象

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


1.全局作用域
由于 window 对象同时扮演着 ECMAScript中 Global 对象的角色,因此所有在全局作用域中声明的变量、函数都会变成 window 对象的属性和方法。


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

全局变量不能通过 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 对象的成员。

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

<xmp>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <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>
</body>
</html>
</xmp>

以上代码创建了一个框架集,其中一个框架居上,两个框架居下。对这个例子而言,可以通过window.frames[0] 或者 window.frames[“topFrame”] 来引用上方的框架。不过,最好使用top 而非 window 来引用这些框架(例如,通过 top.frames[0] )。 top 对象始终指向最高(最外)层的框架,也就是浏览器窗口。使用它可以确保在一个框架中正确地访问另一个框架。因为对于在一个框架中编写的任何代码来说,其中的 window 对象指向的都是那个框架的特定实例,而非最高层的框架。

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

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


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

在 IE、Opera 中,screenLeft 和 screenTop 中保存的是从屏幕左边和上边到由 window 对象表示的页面可见区域的距离。
在 Chrome、Firefox和 Safari中, screenY 或 screenTop中保存的是整个浏览器窗口相对于屏幕的坐标值。

使用 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);

需要注意的是,这两个方法可能会被浏览器禁用;而且,在 Opera 和 IE 7(及更高版本)中默认就是禁用的。另外,这两个方法都不适用于框架,只能对最外层的 window 对象使用。

4.窗口大小
有三种方法能够确定浏览器窗口的尺寸(浏览器的视口,不包括工具栏和滚动条)。

对于Internet Explorer、Chrome、Firefox、Opera 以及 Safari:


window.innerHeight  //浏览器窗口的内部高度
window.innerWidth   //浏览器窗口的内部宽度

对于 Internet Explorer 8、7、6、5:


document.documentElement.clientHeight
document.documentElement.clientWidth
// 或
document.body.clientHeight
document.body.clientWidth

可以综合起来写成以下方式直接调用:


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;
    }
}


var w=window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
var h=window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; 

该例显示浏览器窗口的高度和宽度:(不包括工具栏/滚动条)

5.导航和打开窗口
使用 window.open() 方法既可以导航到一个特定的 URL,也可以打开一个新的浏览器窗口。


var wroxWin = window.open("http://blog.21yt.cc/","_blank","height=400,width=400,top=10,left=10,resizable=yes","true");

window.open() 可以接收 4 个参数:
■ 要加载的 URL: http://blog.21yt.cc/
■ 窗口目标: _self 、 _parent 、 _top 或 _blank 。
■ 一个特性字符串: 见下表
■ 一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值:true、false

设 置说 明
fullscreenyes 或 no表示浏览器窗口是否最大化。仅限IE
height数值表示新窗口的高度。不能小于100
left数值表示新窗口的左坐标。不能是负值
locationyes 或 no表示是否在浏览器窗口中显示地址栏。不同浏览器的默认值不同。如果设置为no,地址栏可能会隐藏,也可能会被禁用(取决于浏览器)
menubaryes 或 no表示是否在浏览器窗口中显示菜单栏。默认值为 no
resizableyes 或 no表示是否可以通过拖动浏览器窗口的边框改变其大小。默认值为 no
scrollbarsyes 或 no表示如果内容在视口中显示不下,是否允许滚动。默认值为 no
statusyes 或 no表示是否在浏览器窗口中显示状态栏。默认值为 no
toolbaryes 或 no表示是否在浏览器窗口中显示工具栏。默认值为 no
top数值表示新窗口的上坐标。不能是负值
width数值表示新窗口的宽度。不能小于100

其他以window.open()相关的方法:


//调整大小
wroxWin.resizeTo(500,500);
//移动位置
wroxWin.moveTo(100,100);
//关闭新打开的窗口。
wroxWin.close();   //仅适用于通过 window.open() 打开的弹出窗口

close()这个方法仅适用于通过 window.open() 打开的弹出窗口。对于浏览器的主窗口,如果没有得到用户的允许是不能关闭它的。不过,弹出窗口倒是可以调用 top.close() 在不经用户允许的情况下关闭自己。弹出窗口关闭之后,窗口的引用仍然还在,但除了像下面这样检测其 closed 属性之外,已经没有其他用处了。

曾经有一段时间,广告商在网上使用弹出窗口达到了肆无忌惮的程度。他们经常把弹出窗口打扮成系统对话框的模样,引诱用户去点击其中的广告。由于看起来像是系统对话框,一般用户很难分辨是真是假。为了解决这个问题,有些浏览器开始在弹出窗口配置方面增加限制。

Windows XP SP2 中的 IE6 对弹出窗口施加了多方面的安全限制,包括不允许在屏幕之外创建弹出窗口、不允许将弹出窗口移动到屏幕以外、不允许关闭状态栏等。IE7 则增加了更多的安全限制,如不允许关闭地址栏、默认情况下不允许移动弹出窗口或调整其大小。

Firefox 1 从一开始就不支持修改状态栏,因此无论给 window.open() 传入什么样的特性字符串,弹出窗口中都会无一例外地显示状态栏。后来图灵社区会员StinkBC(StinkBC@gmail.com) 专享 尊重版权的 Firefox 3 又强制始终在弹出窗口中显示地址栏。

Opera 只会在主浏览器窗口中打开弹出窗口,但不允许它们出现在可能与系统对话框混淆的地方。此外,有的浏览器只根据用户操作来创建弹出窗口。这样一来,在页面尚未加载完成时调用window.open() 的语句根本不会执行,而且还可能会将错误消息显示给用户。

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

大多数浏览器都内置有弹出窗口屏蔽程序;
如果是浏览器内置的屏蔽程序阻止的弹出窗口,那么 window.open() 很可能会返回 null 。


var wroxWin = window.open("http://blog.21yt.cc", "_blank");
if (wroxWin == null){
    alert("The popup was blocked!");
}

如果是浏览器扩展或其他程序阻止的弹出窗口,那么 window.open() 通常会抛出一个错误。


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

在任何情况下,以上代码都可以检测出调用 window.open() 打开的弹出窗口是不是被屏蔽了。

评论

0 条评论