JavaScript window 对象详解

1. 概述

window对象 指当前的浏览器窗口,它也是当前页面的顶层对象,即最高一层的对象,全部其余对象都是它的下属。
一个变量若是未声明,那么默认就是顶层对象的属性。javascript

// a是一个没有声明就直接赋值的变量,它自动成为顶层对象的属性。
a = 1;
console.log(window.a) // 1

window 有本身的实体含义,其实不适合看成最高一层的顶层对象,这是一个语言的设计失误。
最先,设计这门语言的时候,原始设想是语言内置的对象越少越好,这样能够提升浏览器的性能。所以,语言设计者 Brendan Eich 就把 window 对象看成顶层对象,全部未声明就赋值的变量都自动变成 window 对象的属性。这种设计使得编译阶段没法检测出未声明变量,但到了今天已经没有办法纠正了。html

2. window 对象的属性

2.1 window.name
window.name属性是一个字符串,表示当前浏览器窗口的名字。
窗口不必定须要名字,这个属性主要配合超连接和表单的target属性使用。java

window.name = 'Hello World!';
console.log(window.name) // "Hello World!"

该属性只能保存字符串,若是写入的值不是字符串,会自动转成字符串。
只要浏览器窗口不关闭,这个属性是不会消失的。
举例来讲,访问a.com时,该页面的脚本设置了window.name,接下来在同一个窗口里面载入了b.com,新页面的脚本能够读到上一个网页设置的 window.name。页面刷新也是这种状况。一旦浏览器窗口关闭后,该属性保存的值就会消失,由于这时窗口已经不存在了。数组

2.2 window.closed,window.opener浏览器

2.2.1 window.closed 属性返回一个布尔值,表示窗口是否关闭;安全

window.closed // false

上面代码检查当前窗口是否关闭。这种检查意义不大,由于只要能运行代码,当前窗口确定没有关闭。
这个属性通常用来检查,使用脚本打开的新窗口是否关闭。服务器

var popup = window.open();
if ((popup !== null) && !popup.closed) {
	// 窗口仍然打开着
}

2.2.2 window.opener 属性表示打开当前窗口的父窗口;
若是当前窗口没有父窗口(即直接在地址栏输入打开),则返回null。cookie

// 表达式会打开一个新窗口,而后返回 true
window.open().opener === window // true

若是两个窗口之间不须要通讯,建议将子窗口的 opener 属性显式设为 null,这样能够减小一些安全隐患。session

// 子窗口的 opener 属性设为 null,两个窗口之间就没办法再联系了
var newWin = window.open('example.html', 'newWindow', 'height=400,width=400');
newWin.opener = null;

经过 opener 属性,能够得到父窗口的全局属性和方法,但只限于两个窗口同源的状况,且其中一个窗口由另外一个打开。
< a > 元素添加 rel=“noopener” 属性,能够防止新打开的窗口获取父窗口,减轻被恶意网站修改父窗口 URL 的风险。框架

<a href="https://an.evil.site" target="_blank" rel="noopener"> 恶意网站 </a>

2.3 window.self,window.window
window.self和window.window属性都指向窗口自己,这两个属性只读

console.log(window.self === window) // true
console.log(window.window === window) // true

2.4 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 应该是相等的
window.frames.length === window.length // true

2.5 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 > 元素。

2.6 window.top,window.parent
window.top 属性指向最顶层窗口,主要用于在框架窗口(frame)里面获取顶层窗口;
window.parent 属性指向父窗口。若是当前窗口没有父窗口,window.parent指向自身;
对于不包含框架的网页,这两个属性等同于window对象

if (window.parent !== window.top) {
  // 代表当前窗口嵌入不止一层
}

2.7 window.status
window.status属性用于读写浏览器状态栏的文本。
注意: 如今不少浏览器都不容许改写状态栏文本,因此使用这个方法不必定有效。

2.8 window.devicePixelRatio
window.devicePixelRatio属性返回一个数值,表示一个 CSS 像素的大小与一个物理像素的大小之间的比率。
它表示一个 CSS 像素由多少个物理像素组成。它能够用于判断用户的显示环境,若是这个比率较大,就表示用户正在使用高清屏幕,所以能够显示较大像素的图片。

3. 位置大小属性

3.1 window.screenX,window.screenY(只读)
window.screenX和window.screenY属性,返回浏览器窗口左上角相对于当前屏幕左上角的水平距离和垂直距离(单位像素)。

3.2 window.innerHeight,window.innerWidth(只读)
window.innerHeight和window.innerWidth属性,返回网页在当前窗口中可见部分的高度和宽度,即“视口”(viewport)的大小(单位像素)。

用户放大网页的时候(好比将网页从100%的大小放大为200%),这两个属性会变小。由于这时网页的像素大小不变(好比宽度仍是960像素),只是每一个像素占据的屏幕空间变大了,由于可见部分(视口)就变小了。

注意,这两个属性值包括滚动条的高度和宽度。

3.3 window.outerHeight,window.outerWidth(只读)
window.outerHeight 和 window.outerWidth 属性返回浏览器窗口的高度和宽度,包括浏览器菜单和边框(单位像素)。

3.4 window.scrollX,window.scrollY(只读)
window.scrollX属性返回页面的水平滚动距离,window.scrollY属性返回页面的垂直滚动距离,单位都为像素。

注意: 这两个属性的返回值不是整数,而是双精度浮点数。若是页面没有滚动,它们的值就是0。
举例来讲,若是用户向下拉动了垂直滚动条75像素,那么window.scrollY就是75左右。用户水平向右拉动水平滚动条200像素,window.scrollX就是200左右。

// 若是页面向下滚动的距离小于75像素,那么页面向下滚动75像素
if (window.scrollY < 75) {
  window.scroll(0, 75);
}

3.5 window.pageXOffset,window.pageYOffset
window.pageXOffset属性和window.pageYOffset属性,是window.scrollX和window.scrollY别名。

4. 组件属性

组件属性返回浏览器的组件对象。

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

5. 全局对象属性

全局对象属性指向一些浏览器原生的全局对象。

window.document  // 指向document对象。注意,这个属性有同源限制。只有来自同源的脚本才能读取这个属性。
window.location  // 指向Location对象,用于获取当前窗口的 URL 信息。它等同于document.location属性。
window.navigator  // 指向Navigator对象,用于获取环境信息。
window.history  // 指向History对象,表示浏览器的浏览历史。
window.localStorage  // 指向本地储存的localStorage数据。
window.sessionStorage  // 指向本地储存的sessionStorage数据。
window.console  // 指向console对象,用于操做控制台。
window.screen  // 指向Screen对象,表示屏幕信息。
window.isSecureContext  // 属性返回一个布尔值,表示当前窗口是否处在加密环境。若是是 HTTPS 协议,就是true,不然就是false。

6. window 对象的方法

6.1 window.alert() , window.prompt() , window.confirm()
这三个方法都具备堵塞效应,一旦弹出对话框,整个页面就是暂停执行,等待用户作出反应。

window.alert() 方法弹出的对话框,只有一个“肯定”按钮,每每用来通知用户某些信息。
用户只有点击“肯定”按钮,对话框才会消失。对话框弹出期间,浏览器窗口处于冻结状态,若是不点“肯定”按钮,用户什么也干不了。
window.alert()方法的参数只能是字符串,无法使用 CSS 样式,可是能够用\n指定换行。

window.alert('Hello World');
alert('本条提示\n分红两行');

window.prompt() 方法弹出的对话框,提示文字的下方,还有一个输入框,要求用户输入信息,并有“肯定”和“取消”两个按钮。
window.prompt()方法的第二个参数是可选的,可是最好老是提供第二个参数,做为输入框的默认值。
它每每用来获取用户输入的数据。

// 代码会跳出一个对话框,文字提示为“您的年龄?”,要求用户在对话框中输入本身的年龄(默认显示25)。用户填入的值,会做为返回值存入变量result。
var result = prompt('您的年龄?', 25)
console.log(result)

window.prompt()的返回值有两种状况,多是字符串(有多是空字符串),也有多是null。
具体分红三种状况:

  1. 用户输入信息,并点击“肯定”,则用户输入的信息就是返回值。
  2. 用户没有输入信息,直接点击“肯定”,则输入框的默认值就是返回值。
  3. 用户点击了“取消”(或者按了 ESC 按钮),则返回值是null。

window.confirm() 方法弹出的对话框,除了提示信息以外,只有“肯定”和“取消”两个按钮,每每用来征询用户是否赞成。
confirm方法返回一个布尔值,若是用户点击“肯定”,返回true;若是用户点击“取消”,则返回false。

var okay = confirm('Please confirm this message.');
if (okay) {
  // 用户按下“肯定”
} else {
  // 用户按下“取消”
}

confirm的一个用途是,用户离开当前页面时,弹出一个对话框,问用户是否真的要离开。

window.onunload = function () {
  return window.confirm('你肯定要离开当面页面吗?');
}

6.2 window.open(), window.close(), window.stop()

window.open() 方法用于新建另外一个浏览器窗口,相似于浏览器菜单的新建窗口选项。它会返回新窗口的引用,若是没法新建窗口,则返回null。

// 浏览器弹出一个新建窗口,网址是当前域名下的somefile.html
var popup = window.open('somefile.html');

open方法一共能够接受三个参数:

window.open(url, windowName, [windowFeatures])

url:字符串,表示新窗口的网址。若是省略,默认网址就是about:blank。
windowName:字符串,表示新窗口的名字。
			若是该名字的窗口已经存在,则占用该窗口,再也不新建窗口。
			若是省略,就默认使用_blank,表示新建一个没有名字的窗口。
			另外还有几个预设值,_self表示当前窗口,_top表示顶层窗口,_parent表示上一层窗口。
windowFeatures:字符串,内容为逗号分隔的键值对(以下所列),表示新窗口的参数,好比有没有提示栏、工具条等等。
				若是省略,则默认打开一个完整的新窗口。
				若是新建的是一个已经存在的窗口,则该参数不起做用,浏览器沿用之前窗口的参数。
				
				第三个参数能够设定以下属性:
					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=一、status都会获得一样的结果。
					若是想设为关闭,不用写no,而是直接省略这个属性便可。
					若是在第三个参数中设置了一部分属性,其余没有被设置的yes/no属性都会被设成no;
					只有titlebar和关闭按钮除外(它们的值默认为yes)。
// 打开的新窗口高度和宽度都为200像素,没有地址栏,但有状态栏和滚动条,容许用户调整大小。
var popup = window.open(
  'somepage.html',
  'DefinitionsWindows',
  '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"

注意: 若是新窗口和父窗口不是同源的(即不在同一个域),它们彼此不能获取对方窗口对象的内部属性。

// 打开一个新窗口,而后在该窗口弹出一个对话框,再将网址导向example.com
var w = window.open();
console.log('已经打开新窗口');
w.location = 'http://example.com';

因为open这个方法很容易被滥用,许多浏览器默认都不容许脚本自动新建窗口。
只容许在用户点击连接或按钮时,脚本作出反应,弹出新窗口。所以,有必要检查一下打开新窗口是否成功。

var popup = window.open();
if (popup === null) {
  // 新建窗口失败
}

window.close() 方法用于关闭当前窗口,通常只用来关闭window.open方法新建的窗口。
该方法只对顶层窗口有效,iframe框架之中的窗口使用该方法无效。

window.close()

window.stop() 方法彻底等同于单击浏览器的中止按钮,会中止加载图像、视频等正在或等待加载的对象。

window.stop()

6.3 window.moveTo(), window.resizeBy()
注意: 为了防止有人滥用这两个方法,随意移动用户的窗口,目前只有一种状况,浏览器容许用脚本移动窗口:该窗口是用window.open方法新建的,而且它所在的 Tab 页是当前窗口里面惟一的。除此之外的状况,使用上面两个方法都是无效的。

window.moveTo() 方法用于移动浏览器窗口到指定位置。
它接受两个参数,分别是窗口左上角距离屏幕左上角的水平距离和垂直距离,单位为像素。

// 将窗口移动到屏幕(100, 200)的位置
window.moveTo(100, 200)

window.moveBy() 方法将窗口移动到一个相对位置。
它接受两个参数,分布是窗口左上角向右移动的水平距离和向下移动的垂直距离,单位为像素。

// 将窗口向右移动25像素、向下移动50像素
window.moveBy(25, 50)

6.4 window.scrollTo(),window.scroll(),window.scrollBy()

window.scrollTo() 方法用于将文档滚动到指定位置。
接受两个参数,表示滚动后位于窗口左上角的页面坐标。

window.scrollTo(x-coord, y-coord)

也能够接受一个配置对象做为参数。

window.scrollTo(options)
配置对象options有三个属性:
  top:滚动后页面左上角的垂直坐标,即y坐标。
  left:滚动后页面左上角的水平坐标,即x坐标。
  behavior:字符串,表示滚动的方式,有三个可能值(smooth、instant、auto),默认值为auto。

window.scrollTo({
  top: 1000,
  behavior: 'smooth'
});

window.scroll() 方法是 window.scrollTo() 方法的别名。

window.scrollBy() 方法用于将网页滚动指定距离(单位像素)。
它接受两个参数:水平向右滚动的像素,垂直向下滚动的像素。

// 用于将网页向下滚动一屏
window.scrollBy(0, window.innerHeight)
若是不是要滚动整个文档,而是要滚动某个元素,可使用下面三个属性和方法:
Element.scrollTop
Element.scrollLeft
Element.scrollIntoView()

6.5 window.print()
window.print() 方法会跳出打印对话框,与用户点击菜单里面的“打印”命令效果相同。

// 常见的打印按钮代码以下
document.getElementById('printLink').onclick = function () {
  window.print();
}
// 非桌面设备(好比手机)可能没有打印功能,这时能够这样判断
if (typeof window.print === 'function') {
  // 支持打印功能
}

6.6 window.focus(),window.blur()
window.focus() 方法会激活窗口,使其得到焦点,出如今其余窗口的前面。

// 先检查popup窗口是否依然存在,确认后激活该窗口
var popup = window.open('popup.html', 'Popup Window');

if ((popup !== null) && !popup.closed) {
  popup.focus();
}

window.blur() 方法将焦点从窗口移除。

当前窗口得到焦点时,会触发focus事件;当前窗口失去焦点时,会触发blur事件。

6.7 window.getSelection()
window.getSelection方法返回一个Selection对象,表示用户如今选中的文本。

var selObj = window.getSelection();
// 使用Selection对象的toString方法能够获得选中的文本
var selectedText = selObj.toString();

6.8 window.getComputedStyle(),window.matchMedia()

window.getComputedStyle() 方法接受一个元素节点做为参数,返回一个包含该元素的最终样式信息的对象。
window.matchMedia() 方法用来检查 CSS 的mediaQuery语句。

6.9 window.requestAnimationFrame()

window.requestAnimationFrame() 方法跟 setTimeout 相似,都是推迟某个函数的执行。
不一样之处在于: setTimeout 必须指定推迟的时间,window.requestAnimationFrame() 则是推迟到浏览器下一次重流时执行,执行完才会进行下一次重绘。重绘一般是 16ms 执行一次,不过浏览器会自动调节这个速率,好比网页切换到后台 Tab 页时,requestAnimationFrame()会暂停执行。

若是某个函数会改变网页的布局,通常就放在window.requestAnimationFrame()里面执行,这样能够节省系统资源,使得网页效果更加平滑。由于慢速设备会用较慢的速率重流和重绘,而速度更快的设备会有更快的速率。

window.requestAnimationFrame(callback)

callback是一个回调函数。
callback执行时,它的参数就是系统传入的一个高精度时间戳(performance.now()的返回值),单位是毫秒,表示距离网页加载的时间。

window.requestAnimationFrame()的返回值是一个整数,这个整数能够传入window.cancelAnimationFrame(),用来取消回调函数的执行。
// 下面是一个window.requestAnimationFrame()执行网页动画的例子,持续时间是2秒,会让元素向右移动。
var element = document.getElementById('animate');
element.style.position = 'absolute';

var start = null;

function step(timestamp) {
  if (!start) start = timestamp;
  var progress = timestamp - start;
  // 元素不断向左移,最大不超过200像素
  element.style.left = Math.min(progress / 10, 200) + 'px';
  // 若是距离第一次执行不超过 2000 毫秒,
  // 就继续执行动画
  if (progress < 2000) {
    window.requestAnimationFrame(step);
  }
}

window.requestAnimationFrame(step);

6.10 window.requestIdleCallback()
window.requestIdleCallback()跟setTimeout相似,也是将某个函数推迟执行,可是它保证将回调函数推迟到系统资源空闲时执行。也就是说,若是某个任务不是很关键,就可使用window.requestIdleCallback()将其推迟执行,以保证网页性能。

它跟window.requestAnimationFrame() 的区别: 后者指定回调函数在下一次浏览器重排时执行,问题在于下一次重排时,系统资源未必空闲,不必定能保证在16毫秒以内完成;window.requestIdleCallback()能够保证回调函数在系统资源空闲时执行。

window.requestIdleCallback(callback[, options])

callback参数是一个回调函数。
该回调函数执行时,系统会传入一个IdleDeadline对象做为参数。
IdleDeadline对象有一个didTimeout属性(布尔值,表示是否为超时调用)和一个timeRemaining()方法(返回该空闲时段剩余的毫秒数)。
options参数是一个配置对象,目前只有timeout一个属性,用来指定回调函数推迟执行的最大毫秒数,该参数可选。

window.requestIdleCallback()方法返回一个整数,该整数能够传入window.cancelIdleCallback()取消回调函数。
// requestIdleCallback()用来执行非关键任务myNonEssentialWork。该任务先确认本次空闲时段有剩余时间,而后才真正开始执行任务
requestIdleCallback(myNonEssentialWork);

function myNonEssentialWork(deadline) {
  while (deadline.timeRemaining() > 0) {
    doWorkIfNeeded();
  }
}
// processPendingAnalyticsEvents必须在将来2秒以内执行
requestIdleCallback(processPendingAnalyticsEvents, { timeout: 2000 });

若是因为超时致使回调函数执行,则 deadline.timeRemaining() 返回 0,deadline.didTimeout 返回true。

若是屡次执行 window.requestIdleCallback(),指定多个回调函数,那么这些回调函数将排成一个队列,按照先进先出的顺序执行。

7. 事件

window对象能够接收如下事件

7.1 load 事件和 onload 属性
load事件发生在文档在浏览器窗口加载完毕时,window.onload属性能够指定这个事件的回调函数;

// 在网页加载完毕后,获取指定元素并进行处理
window.onload = function() {
  var elements = document.getElementsByClassName('example');
  for (var i = 0; i < elements.length; i++) {
    var elt = elements[i];
    // ...
  }
};

7.2 error 事件和 onerror 属性
浏览器脚本发生错误时,会触发 window 对象的 error 事件,能够经过 window.onerror 属性对该事件指定回调函数。

window.onerror = function (message, filename, lineno, colno, error) {
  console.log("出错了!--> %s", error.stack);
};

window的error事件的回调函数不接受错误对象做为参数,而是一共能够接受五个参数,它们的含义依次以下:
出错信息, 出错脚本的网址, 行号, 列号, 错误对象

老式浏览器只支持前三个参数。

不是全部的错误,都会触发 JavaScript 的error事件(即让 JavaScript 报错)。
通常来讲,只有 JavaScript 脚本的错误,才会触发这个事件,而像资源文件不存在之类的错误,都不会触发。
// 若是整个页面未捕获错误超过3个,就显示警告
window.onerror = function(msg, url, line) {
  if (onerror.num++ > onerror.max) {
    alert('ERROR: ' + msg + '\n' + url + ':' + line);
    return true;
  }
}
onerror.max = 3;
onerror.num = 0;

注意: 若是脚本网址与网页网址不在同一个域(好比使用了 CDN),浏览器根本不会提供详细的出错信息,只会提示出错,错误类型是“Script error.”,行号为0,其余信息都没有。这是浏览器防止向外部脚本泄漏信息。
一个解决方法是在脚本所在的服务器,设置Access-Control-Allow-Origin的 HTTP 头信息:

Access-Control-Allow-Origin: *
// 在网页的<script>标签中设置crossorigin属性
<script crossorigin="anonymous" src="//example.com/file.js"></script>

上面代码的 crossorigin="anonymous" 表示,读取文件不须要身份信息,即不须要 cookie 和 HTTP 认证信息。
若是设为crossorigin="use-credentials",就表示浏览器会上传 cookie 和 HTTP 认证信息,
同时还须要服务器端打开 HTTP 头信息Access-Control-Allow-Credentials。

7.3 window 对象的事件监听属性

window.onafterprint  // afterprint事件的监听函数。
window.onbeforeprint  // beforeprint事件的监听函数。
window.onbeforeunload  // beforeunload事件的监听函数。
window.onhashchange  // hashchange事件的监听函数。
window.onlanguagechange  // languagechange的监听函数。
window.onmessage  // message事件的监听函数。
window.onmessageerror // MessageError事件的监听函数。
window.onoffline  // offline事件的监听函数。
window.ononline  // online事件的监听函数。
window.onpagehide  // pagehide事件的监听函数。
window.onpageshow  // pageshow事件的监听函数。
window.onpopstate  // popstate事件的监听函数。
window.onstorage  // storage事件的监听函数。
window.onunhandledrejection  // 未处理的Promise对象的reject事件的监听函数。
window.onunload  // unload事件的监听函数。

8. 多窗口操做

因为网页可使用 iframe 元素,嵌入其余网页,所以一个网页之中会造成多个窗口。若是子窗口之中又嵌入别的网页,就会造成多级窗口。
8.1 窗口的引用
各个窗口之中的脚本,能够引用其余窗口,浏览器提供了一些特殊变量,用来返回其余窗口。

  1. top:顶层窗口,即最上层的那个窗口;
  2. parent:父窗口;
  3. self:当前窗口,即自身;
// 判断当前窗口是否为顶层窗口
if (window.top === window.self) {
  // 当前窗口是顶层窗口
} else {
  // 当前窗口是子窗口
}

// 判断,当前窗口是否为顶层窗口
window.parent.history.back();

与这些变量对应,浏览器还提供一些特殊的窗口名,供window.open()方法、< a > 标签、< form > 标签等引用。

  1. _top:顶层窗口;
  2. _parent:父窗口;
  3. _blank:新窗口;
// 在顶层窗口打开连接
<a href="somepage.html" target="_top">Link</a>

8.2 iframe 元素
对于 iframe 嵌入的窗口,document.getElementById 方法能够拿到该窗口的 DOM 节点,而后使用 contentWindow 属性得到iframe 节点包含的 window 对象。

var frame = document.getElementById('theFrame');
var frameWindow = frame.contentWindow;

// 上面代码中,frame.contentWindow 能够拿到子窗口的 window 对象。而后,在知足同源限制的状况下,能够读取子窗口内部的属性。
// 获取子窗口的标题
frameWindow.title

< iframe > 元素的 contentDocument 属性,能够拿到子窗口的 document 对象。

var frame = document.getElementById('theFrame');
var frameDoc = frame.contentDocument;

// 等同于
var frameDoc = frame.contentWindow.document;

< iframe >元素遵照同源政策,只有当父窗口与子窗口在同一个域时,二者之间才能够用脚本通讯,不然只有使用window.postMessage 方法。

<iframe> 窗口内部,使用 window.parent 引用父窗口。若是当前页面没有父窗口,则 window.parent 属性返回自身。
所以,能够经过 window.parent 是否等于 window.self,判断当前窗口是否为 iframe 窗口。
if (window.parent !== window.self) {
  // 当前窗口是子窗口
}


<iframe>窗口的window对象,有一个frameElement属性,返回<iframe>在父窗口中的 DOM 节点。对于非嵌入的窗口,该属性等于null。
var f1Element = document.getElementById('f1');
var f1Window = f1Element.contentWindow;
f1Window.frameElement === f1Element // true
window.frameElement === null // true

8.3 window.frames 属性
window.frames 属性返回一个相似数组的对象,成员是全部子窗口的 window 对象。可使用这个属性,实现窗口之间的互相引用。
如:frames[0]返回第一个子窗口,frames[1].frames[2]返回第二个子窗口内部的第三个子窗口,parent.frames[1]返回父窗口的第二个子窗口。

注意: window.frames 每一个成员的值,是框架内的窗口(即框架的window对象),而不是iframe标签在父窗口的 DOM 节点。若是要获取每一个框架内部的 DOM 树,须要使用 window.frames[0].document 的写法。

若是 <iframe> 元素设置了name或id属性,那么属性值会自动成为全局变量,可经过 window.frames 属性引用,返回子窗口的 window 对象。

// HTML 代码为 <iframe id="myFrame">
window.myFrame // [HTMLIFrameElement]
frames.myframe === myFrame // true

name属性的值会自动成为子窗口的名称,能够用在window.open方法的第二个参数,或者<a>和<frame>标签的target属性
相关文章
相关标签/搜索