window.open
1. 参数
window.open
常用来在新的window
或新的tab
页打开一个页面或文件(如图片、PDF等),它支持三个参数:
strUrl
:要打开的页面或资源的url地址。strWindowName
:窗口的名字,用于后续对该窗口的引用,不是窗口的标题。strWindowFeatures
:窗口的描述参数,如尺寸、位置、是否启用工具栏等。
该方法的返回值是新打开的窗口的引用,也就是新窗口的window
对象。在遵循同源策略的情况下,可以直接通过该对象访问被打开的页面;即使在跨域的情况下,也可以通过window.postMessage
向其发消息。
我们分别来解读这三个参数的用法:
(1). strUrl
打开的窗口中要加载的url,可以是一个HTML页面,或者其他任何浏览器能打开的资源文件。
要加载的url可以是同域的,也可以是跨域的。在跨域条件下,window.open
满足和跨域的iframe
一样的限制。从通信的角度来说,使用window.open
打开窗口和在内嵌的iframe
内打开页面是等价的,两者的差异更多是在于视觉效果的不同。
strUrl允许传入空值。此时第二个参数必须传入一个已打开的窗口的名字,从而获取这个窗口的引用:
// 打开一个窗口
let win = window.open('https://www.baidu.com', 'baidu');
// 通过窗口名获取上述窗口
let refWin = window.open('', 'baidu');
这样就可以在不打开新窗口的情况下获得窗口名为'baidu'
的窗口的引用。
(2). strWindowName
该参数是被打开的窗口的名字,注意,它并不是窗口的标题。该参数只是一个窗口标识,用于以后通过它来找到对应的窗口的引用。
比如在上面的例子中,我们可以通过'baidu'
这个名字来找到刚打开的百度的窗口,这样就不需要在全局变量中保存该窗口的引用了(它的代价不在于内存损耗,而在于对全局变量的维护)。
该参数除了支持普通的名字外,还支持和a
标签一样的特殊关键字:_self
、_blank
、_parent
和_top
,分别用于在当前窗口
、空白窗口
、父窗口
和顶级窗口
中打开该窗口,具体的行为请参考a
标签的target
属性。
当传入了已经被使用过的窗口的名字时,不会新打开一个窗口,而是在该名字对应的窗口中打开,该窗口之前加载的内容会被替换。
// 在上述窗口打开csdn首页
window.open('https://csdn.net', 'baidu');
如果总是想打开新页面,可以给第二个参数传入'_blank'
。不过此时如果需要引用这些窗口,需要即时保存窗口的引用。
(3). strWindowFeatures
窗口参数描述,字符串类型,各个参数由逗号隔开,参数之间以等号连接。比如下面的例子可以在距当前window左上角(10, 10)
位置处打开一个宽度400像素,高度200像素的窗口:
window.open('https://www.baidu.com',
'baidu',
'top=10,left=10,width=400,height=200');
下面我们来看一些常用参数(图片来自mdn,由于不同浏览器的页面结构不一样,因此不是每个参数对每个浏览器都生效,具体请以实际效果为准。在Chrome中,基本只支持left、top、height和width,因此我们暂且仅介绍这四个参数):
left
,新窗口相对于当前浏览器页面左侧的距离。top
,新窗口相对于浏览器页面顶部的位置,注意,不是相对于文档区域,而是整个浏览器页面。height
,窗口内容区(即用户区,不包含工具栏、标签栏等)的高度,单位像素,最小值100。weight
,窗口的宽度(包含滚动条),单位像素,最小值100。
其他参数如menubar、toolbar、location、personalbar等在Chrome中均不支持,如果需要在其他浏览器中启用,请参考mdn – window.open。
2. 返回值
window.open
返回的是对新打开的窗口的引用,即该窗口的window对象:
let refWin = window.open('https://www.baidu.com', 'baidu');
console.log(refWin);
不过这里引用到的window对象并不具备完整的DOM属性和方法,它仅仅提供了访问该页面的一些基本属性和方法,如图所示。
blur()
,手动移除窗口焦点的方法,refWin.blur()
可使该窗口失去焦点。close()
,关闭该窗口的方法。closed
,标识该窗口是否已经被关闭。frames
,新窗口内的frames
。length
,新窗口内iframes的数量。location
,新窗口window的location对象,用于访问窗口的地址信息。opener
,该窗口的打开者。如我们在a
页面通过window.open
打开b
页面,那么b
页面的window.opener
就是a
页面的window。parent
,该窗口的父窗口,由于是顶级窗口,因此它的值等于window自身。postMessage
,通信接口,通过该方法可以实现向新窗口发送消息,优势是支持跨域。self
、window
、top
,前两个均代指当前window,top
指的是当前窗口所在页面的顶级窗口,由于自身已经是顶级窗口,因此top
也是当前window。
3. 通信问题
使用window.open
打开新窗口时,原窗口与新窗口之间是可以实现双向通信的。
在不跨域的情况下,可以直接访问页面内的任何全局变量、方法或DOM元素等。新窗口通过window.opener
可以找到原窗口的window;而原窗口可以直接通过window.open
的返回值访问新窗口,或者通过该窗口的名字找到该窗口,方法为:let ref = window.open('', 'windowName')
。
由于新窗口的加载是异步的,因此不能在调用window.open
之后立即访问该窗口。可以在窗口的onload事件内访问新窗口:
let ref = window.open('/index.html');
ref.onload = function(){
... // 与新窗口通信
}
而在新页面中,可以直接通过window.opener
访问原窗口,如:
// 查找原窗口内的p元素
let p = document.querySelectorAll('p',
window.opener.document);
在跨域的情况下,以上的方法会报错,因为会受到浏览器跨域安全策略的限制,此时就需要通过window.postMessage
实现页面之间的通信。
在原窗口,可以通过对新窗口的引用调用postMessage:
let ref = window.open('https://www.baidu.com');
ref.postMessage(data, '*');
在新窗口内,同样通过window.opener
访问原窗口:
window.opener.postMessage(data, '*');
在使用postMessage进行通信的时候存在一个小的兼容性问题,那就是IE8和IE9中的独立窗口之间通信时只能传递字符串,不支持其他数据类型,而在与页面内的iframe通信时没有这个问题。
总结
window.open
本质上可以看做<a>
标签的js
版本,或者说是编码式地打开窗口。但它比<a>
标签更加灵活,可以通过js
实现与打开的页面之间的通信。
今天的文章window.open用法详解分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/30751.html