window 对象
概述
浏览器里面,window对象(注意,w为小写)指当前的浏览器窗口。它也是当前页面的顶层对象,即最高一层的对象,所有其他对象都是它的下属。一个变量如果未声明,那么默认就是顶层对象的属性。
a = 1;
window.a // 1
上面代码中,a是一个没有声明就直接赋值的变量,它自动成为顶层对象的属性。
window有自己的实体含义,其实不适合当作最高一层的顶层对象,这是一个语言的设计失误。最早,设计这门语言的时候,原始设想是语言内置的对象越少越好,这样可以提高浏览器的性能。因此,语言设计者 Brendan Eich 就把window对象当作顶层对象,所有未声明就赋值的变量都自动变成window对象的属性。这种设计使得编译阶段无法检测出未声明变量,但到了今天已经没有办法纠正了。
window 对象的属性
window.name
window.name属性是一个字符串,表示当前浏览器窗口的名字。窗口不一定需要名字,这个属性主要配合超链接和表单的target属性使用。
window.name = 'Hello World!';
console.log(window.name)
// "Hello World!"
该属性只能保存字符串,如果写入的值不是字符串,会自动转成字符串。各个浏览器对这个值的储存容量有所不同,但是一般来说,可以高达几MB。
只要浏览器窗口不关闭,这个属性是不会消失的。举例来说,访问a.com时,该页面的脚本设置了window.name,接下来在同一个窗口里面载入了b.com,新页面的脚本可以读到上一个网页设置的window.name。页面刷新也是这种情况。一旦浏览器窗口关闭后,该属性保存的值就会消失,因为这时窗口已经不存在了。
window.closed,window.opener
window.closed属性返回一个布尔值,表示窗口是否关闭。
window.closed // false
上面代码检查当前窗口是否关闭。这种检查意义不大,因为只要能运行代码,当前窗口肯定没有关闭。这个属性一般用来检查,使用脚本打开的新窗口是否关闭。
var popup = window.open();
if ((popup !== null) && !popup.closed) {
// 窗口仍然打开着
}
window.opener属性表示打开当前窗口的父窗口。如果当前窗口没有父窗口(即直接在地址栏输入打开),则返回null。
window.open().opener === window // true
上面表达式会打开一个新窗口,然后返回true。
如果两个窗口之间不需要通信,建议将子窗口的opener属性显式设为null,这样可以减少一些安全隐患。
var newWin = window.open('example.html', 'newWindow', 'height=400,width=400');
newWin.opener = null;
上面代码中,子窗口的opener属性设为null,两个窗口之间就没办法再联系了。
通过opener属性,可以获得父窗口的全局属性和方法,但只限于两个窗口同源的情况(参见《同源限制》一章),且其中一个窗口由另一个打开。<a>元素添加rel="noopener"属性,可以防止新打开的窗口获取父窗口,减轻被恶意网站修改父窗口 URL 的风险。
<a href="https://an.evil.site" target="_blank" rel="noopener">
恶意网站
</a>
window.self,window.window
window.self和window.window属性都指向窗口本身。这两个属性只读。
window.self === window // true
window.window === window // true
window.frames,window.length
window.frames属性返回一个类似数组的对象,成员为页面内所有框架窗口,包括frame元素和iframe元素。window.frames[0]表示页面中第一个框架窗口。
如果iframe元素设置了id或name属性,那么就可以用属性值,引用这个iframe窗口。比如<iframe name="myIFrame">可以用frames['myIFrame']或者frames.myIFrame来引用。
frames属性实际上是window对象的别名。
frames === window // true
因此,frames[0]也可以用window[0]表示。但是,从语义上看,frames更清晰,而且考虑到window还是全局对象,因此推荐表示多窗口时,总是使用frames[0]的写法。更多介绍请看下文的《多窗口操作》部分。
window.length属性返回当前网页包含的框架总数。如果当前网页不包含frame和iframe元素,那么window.length就返回0。
window.frames.length === window.length // true
上面代码表示,window.frames.length与window.length应该是相等的。
window.frameElement
window.frameElement属性主要用于当前窗口嵌在另一个网页的情况(嵌入<object>、<iframe>或<embed>元素),返回当前窗口所在的那个元素节点。如果当前窗口是顶层窗口,或者所嵌入的那个网页不是同源的,该属性返回null。
// HTML 代码如下
// <iframe src="about.html"></iframe>
// 下面的脚本在 about.html 里面
var frameEl = window.frameElement;
if (frameEl) {
frameEl.src = 'other.html';
}
上面代码中,frameEl变量就是<iframe>元素。
window.top,window.parent
window.top属性指向最顶层窗口,主要用于在框架窗口(frame)里面获取顶层窗口。
window.parent属性指向父窗口。如果当前窗口没有父窗口,window.parent指向自身。
if (window.parent !== window.top) {
// 表明当前窗口嵌入不止一层
}
对于不包含框架的网页,这两个属性等同于window对象。
window.status
window.status属性用于读写浏览器状态栏的文本。但是,现在很多浏览器都不允许改写状态栏文本,所以使用这个方法不一定有效。
window.devicePixelRatio
window.devicePixelRatio属性返回一个数值,表示一个 CSS 像素的大小与一个物理像素的大小之间的比率。也就是说,它表示一个 CSS 像素由多少个物理像素组成。它可以用于判断用户的显示环境,如果这个比率较大,就表示用户正在使用高清屏幕,因此可以显示较大像素的图片。
位置大小属性
以下属性返回window对象的位置信息和大小信息。
(1)window.screenX,window.screenY
window.screenX和window.screenY属性,返回浏览器窗口左上角相对于当前屏幕左上角的水平距离和垂直距离(单位像素)。这两个属性只读。
(2) window.innerHeight,window.innerWidth
window.innerHeight和window.innerWidth属性,返回网页在当前窗口中可见部分的高度和宽度,即“视口”(viewport)的大小(单位像素)。这两个属性只读。
用户放大网页的时候(比如将网页从100%的大小放大为200%),这两个属性会变小。因为这时网页的像素大小不变(比如宽度还是960像素),只是每个像素占据的屏幕空间变大了,因此可见部分(视口)就变小了。
注意,这两个属性值包括滚动条的高度和宽度。
(3)window.outerHeight,window.outerWidth
window.outerHeight和window.outerWidth属性返回浏览器窗口的高度和宽度,包括浏览器菜单和边框(单位像素)。这两个属性只读。
(4)window.scrollX,window.scrollY
window.scrollX属性返回页面的水平滚动距离,window.scrollY属性返回页面的垂直滚动距离,单位都为像素。这两个属性只读。
注意,这两个属性的返回值不是整数,而是双精度浮点数。如果页面没有滚动,它们的 值就是0。
举例来说,如果用户向下拉动了垂直滚动条75像素,那么window.scrollY就是75左右。用户水平向右拉动水平滚动条200像素,window.scrollX就是200左右。
if (window.scrollY < 75) {
window.scroll(0, 75);
}
上面代码中,如果页面向下滚动的距离小于75像素,那么页面向下滚动75像素。
(5)window.pageXOffset,window.pageYOffset
window.pageXOffset属性和window.pageYOffset属性,是window.scrollX和window.scrollY别名。
组件属性
组件属性返回浏览器的组件对象。这样的属性有下面几个。
window.locationbar:地址栏对象window.menubar:菜单栏对象window.scrollbars:窗口的滚动条对象window.toolbar:工具栏对象window.statusbar:状态栏对象window.personalbar:用户安装的个人工具栏对象
这些对象的visible属性是一个布尔值,表示这些组件是否可见。这些属性只读。
window.locationbar.visible
window.menubar.visible
window.scrollbars.visible
window.toolbar.visible
window.statusbar.visible
window.personalbar.visible
全局对象属性
全局对象属性指向一些浏览器原生的全局对象。
window.document:指向document对象,详见《document 对象》一章。注意,这个属性有同源限制。只有来自同源的脚本才能读取这个属性。window.location:指向Location对象,用于获取当前窗口的 URL 信息。它等同于document.location属性,详见《Location 对象》一章。window.navigator:指向Navigator对象,用于获取环境信息,详见《Navigator 对象》一章。window.history:指向History对象,表示浏览器的浏览历史,详见《History 对象》一章。window.localStorage:指向本地储存的 localStorage 数据,详见《Storage 接口》一章。window.sessionStorage:指向本地储存的 sessionStorage 数据,详见《Storage 接口》一章。window.console:指向console对象,用于操作控制台,详见《console 对象》一章。window.screen:指向Screen对象,表示屏幕信息,详见《Screen 对象》一章。
window.isSecureContext
window.isSecureContext属性返回一个布尔值,表示当前窗口是否处在加密环境。如果是 HTTPS 协议,就是true,否则就是false。
window 对象的方法
window.alert(),window.prompt(),window.confirm()
window.alert()、window.prompt()、window.confirm()都是浏览器与用户互动的全局方法。它们会弹出不同的对话框,要求用户做出回应。注意,这三个方法弹出的对话框,都是浏览器统一规定的式样,无法定制。
(1)window.alert()
window.alert()方法弹出的对话框,只有一个“确定”按钮,往往用来通知用户某些信息。
window.alert('Hello World');
用户只有点击“确定”按钮,对话框才会消失。对话框弹出期间,浏览器窗口处于冻结状态,如果不点“确定”按钮,用户什么也干不了。
window.alert()方法的参数只能是字符串,没法使用 CSS 样式,但是可以用\n指定换行。
alert('本条提示\n分成两行');
(2)window.prompt()
window.prompt()方法弹出的对话框,提示文字的下方,还有一个输入框,要求用户输入信息,并有“确定”和“取消”两个按钮。它往往用来获取用户输入的数据。
var result = prompt('您的年龄?', 25)
上面代码会跳出一个对话框,文字提示为“您的年龄?”,要求用户在对话框中输入自己的年龄(默认显示25)。用户填入的值,会作为返回值存入变量result。
window.prompt()的返回值有两种情况,可能是字符串(有可能是空字符串),也有可能是null。具体分成三种情况。
- 用户输入信息,并点击“确定”,则用户输入的信息就是返回值。
- 用户没有输入信息,直接点击“确定”,则输入框的默认值就是返回值。
- 用户点击了“取消”(或者按了 ESC 按钮),则返回值是
null。
window.prompt()方法的第二个参数是可选的,但是最好总是提供第二个参数,作为输入框的默认值。
(3)window.confirm()
window.confirm()方法弹出的对话框,除了提示信息之外,只有“确定”和“取消”两个按钮,往往用来征询用户是否同意。
var result = confirm('你最近好吗?');
上面代码弹出一个对话框,上面只有一行文字“你最近好吗?”,用户选择点击“确定”或“取消”。
confirm方法返回一个布尔值,如果用户点击“确定”,返回true;如果用户点击“取消”,则返回false。
var okay = confirm('Please confirm this message.');
if (okay) {
// 用户按下“确定”
} else {
// 用户按下“取消”
}
confirm的一个用途是,用户离开当前页面时,弹出一个对话框,问用户是否真的要离开。
window.onunload = function () {
return window.confirm('你确定要离开当面页面吗?');
}
这三个方法都具有堵塞效应,一旦弹出对话框,整个页面就是暂停执行,等待用户做出反应。
window.open(), window.close(),window.stop()
(1)window.open()
window.open方法用于新建另一个浏览器窗口,类似于浏览器菜单的新建窗口选项。它会返回新窗口的引用,如果无法新建窗口,则返回null。
var popup = window.open('somefile.html');
上面代码会让浏览器弹出一个新建窗口,网 址是当前域名下的somefile.html。
open方法一共可以接受三个参数。
window.open(url, windowName, [windowFeatures])
url:字符串,表示新窗口的网址。如果省略,默认网址就是about:blank。windowName:字符串,表示新窗口的名字。如果该名字的窗口已经存在,则占用该窗口,不再新建窗口。如果省略,就默认使用_blank,表示新建一个没有名字的窗口。另外还有几个预设值,_self表示当前窗口,_top表示顶层窗口,_parent表示上一层窗口。windowFeatures:字符串,内容为逗号分隔的键值对(详见下文),表示新窗口的参数,比如有没有提示栏、工具条等等。如果省略,则默认打开一个完整 UI 的新窗口。如果新建的是一个已经存在的窗口,则该参数不起作用,浏览器沿用以前窗口的参数。
下面是一个例子。
var popup = window.open(
'somepage.html',
'DefinitionsWindows',
'height=200,width=200,location=no,status=yes,resizable=yes,scrollbars=yes'
);
上面代码表示,打开的新窗口高度和宽度都为200像素,没有地址栏,但有状态栏和滚动条,允许用户调整大小。
第三个参数可以设定如下属性。
- left:新窗口距离屏幕最左边的距离(单位像素)。注意,新窗口必须是可见的,不能设置在屏幕以外的位置。
- top:新窗口距离屏幕最顶部的距离(单位像素)。
- height:新窗口内容区域的高度(单位像素),不得小于100。
- width:新窗口内容区域的宽度(单位像素),不得小于100。
- outerHeight:整个浏览器窗口的高度(单位像素),不得小于100。
- outerWidth:整个浏览器窗口的宽度(单位像素),不得小于100。
- menubar:是否显示菜单栏。
- toolbar:是否显示工具栏。
- location:是否显示地址栏。
- personalbar:是否显示用户自己安装的工具栏。
- status:是否显示状态栏。
- dependent:是否依赖父窗口。如果依赖,那么父窗口最小化,该窗口也最小化;父窗口关闭,该窗口也关闭。
- minimizable:是否有最小化按钮,前提是
dialog=yes。 - noopener:新窗口将与父窗口切断联系,即新窗口的
window.opener属性返回null,父窗口的window.open()方法也返回null。 - resizable:新窗口是否可以调节大小。
- scrollbars:是否允许新窗口出现滚动条。
- dialog:新窗口标题栏是否出现最大化、最小化、恢复原始大小的控件。
- titlebar:新窗口是否显示标题栏。
- alwaysRaised:是否显 示在所有窗口的顶部。
- alwaysLowered:是否显示在父窗口的底下。
- close:新窗口是否显示关闭按钮。
对于那些可以打开和关闭的属性,设为yes或1或不设任何值就表示打开,比如status=yes、status=1、status都会得到同样的结果。如果想设为关闭,不用写no,而是直接省略这个属性即可。也就是说,如果在第三个参数中设置了一部分属性,其他没有被设置的yes/no属性都会被设成no,只有titlebar和关闭按钮除外(它们的值默认为yes)。
上面这些属性,属性名与属性值之间用等号连接,属性与属性之间用逗号分隔。
'height=200,width=200,location=no,status=yes,resizable=yes,scrollbars=yes'
另外,open()方法的第二个参数虽然可以指定已经存在的窗口,但是不等于可以任意控制其他窗口。为了防止被不相干的窗口控制,浏览器只有在两个窗口同源,或者目标窗口被当前网页打开的情况下,才允许open方法指向该窗口。
window.open方法返回新窗口的引用。
var windowB = window.open('windowB.html', 'WindowB');
windowB.window.name // "WindowB"
注意,如果新窗口和父窗口不是同源的(即不在同一个域),它们彼此不能获取对方窗口对象的内部属性。
下面是另一个例子。
var w = window.open();
console.log('已经打开新窗口');
w.location = 'http://example.com';