最近在做公司的一个即时通讯项目,用户点击按钮,新开一个标签页,使用websocket来和后台进行长链接,新开标签页使用的是window.open方法,这里面涉及到了一些小知识,记录一下。
目前在网上搜索的最多的关于window.open的问题基本都是【如果是在ajax回调中调用了window.open,浏览器出于安全机制会进行拦截】这种问题怎么解决一类,网上很多方案,我就不在这赘述了。其实我下面写的这些网上也都能搜到,我就是把我用到的归纳一下
1.首先你用window.open打开一个新的标签页之后,你是可以用变量来接的,然后你通过你接到的变量可以对你新打开的标签页进行一些操作。
const newTab = window.open('XXXXX')
newTab.close() // 关闭新打开的tab页面
newTab.closed // 返回布尔值,true,新开的标签页未销毁;false 新打开的标签页已关闭(注意是关闭,不是隐藏hidden不活跃状态)
newTab.focus() // 让新打开的标签页处于激活状态,而不用重新reload
newTab.location.href = 'XXXX' // 返回新打开的地址,这个应该都知道
2.有个需要注意的地方是window.open打开页面的过程实际是异步的,这个要怎么理解的,比如下面代码:
const newTab = window.open('XXX');
if(newTab.location.href.indexOf('/login')>-1){
newTab = null
}
上面代码的业务场景比较特殊,就是你点开一个新页面,然后这个页面需要用户登录才能操作,所以后台配了一个拦截器(前后端未分离项目),这样的话实际上你并没有真正打开目标页,而是跳转到了登录页,上面的代码判断了一下如果跳转到登录页,就把newTab置未null,但问题是上面的代码永远不会进入if判断,原因就是window.open方法要等到目标页面或被拦截的页面成功打开之后,你才能拿到最后的location.href,上面的代码在open方法调用之后直接去取location.href并不会拿到期望地址(一般这种操作会直接拿到‘about:blank’),目前我还没找到window.open有类似的回调,所以遇到这种需求的尽量换一种别的解决方式。
3.关于window.open方法的参数问题。
此处我想说的就是他的第二个参数,第一个参数是目标地址,第二个参数是目标页名称(并不是title),如果你连续两次调用window.open,且传入的目标页名称一致,那么不会打开新的标签页,而是reload你刚刚开的页面
今天又发现了一个window.open的兼容性问题,在chrome和Firefox表现正常,在qq浏览器和搜狗浏览器中,使用window.open在a页面打开了一个新的tab页面b,然后在a页面重新打开一个新的tab,然后在新开的tab页再使用window.open去打开b页面。这个时候不会会新开一个tab页。仍会打开之前的b页面,而在chrome和Firefox中会新开一个tab页。