一、前言
最近接到一个需求,从一个标签页A打开标签页B,在标签页B要通过按钮返回标签页A,也就是回到首页功能,记录一下实现的过程。
二、基本实现原理
借助于window.open(url, name)指定name的方式返回。
在A页面设置window.name = 'A',B页面使用window.open('', 'A')的方式返回
三、第一种方案:使用window.opener.name判断
判断是否有opener以及opener的name是否是A页面
js
const AUrl = "A.html";
if(window.opener) {
if(window.opener.name == "A") {
window.open("", A)
}
} else {
widnow.open(AUrl)
}
实现的过程中发现,A打开B页面后,这时候切换到A页面,从浏览器地址栏更改url,此时B页面访问A页面会出现跨域问题,代码做下兼容
js
function toHome() {
const AUrl = "A.html";
if(window.opener) {
try {
let name = window.opener.name; // 获取name可能出现跨域问题
if(name == "A") {
window.open("", 'A'); // 可能会出现A窗口不是所需页面,暂无解决方案
}
} catch(e) {
window.opener = window.open(AUrl)
}
} else {
window.opener = widnow.open(AUrl)
}
}
四、第二种方案:使用postMessage传递信息
B页面通过postMessage传递指令到A页面,A页面获取后返回当前的window.name到B页面。 B页面接收后使用window.open跳转。

js
// A.html
window.addEventListener("message", (e) => {
let data = e.data;
if(data.action == "backHome") {
let name = "A" + Math.round(Math.random() * 10000) // 生成随机数,确保name唯一
window.name = name;
e.source.postMessage({
action: "backHome",
name: name
}, '*')
}
})
// B.html
function toHome() {
let url = 'A.html';
let timer
const callback = (e) => {
let data = e.data;
if(data.action && data.action == "backHome") {
clearTimeout(timer);
window.open("", data.name)
}
window.removeEventListener("message", callback)
}
let opener = window.opener;
if(opener) {
window.addEventListener("message", callback)
opener.postMessage({
action: "backHome"
})
timer = setTimeout(() => {
window.removeEventListener("message", callback)
window.opener = window.open(url);
}, 300);
} else {
window.opener = window.open(url);
}
}