本文为原创, 遵循 CC 4.0 BY-SA 版权协议, 转载需注明出处: https://blog.csdn.net/big_cheng/article/details/129971111.
网站里有时页面要在同一tab(或窗口, 下同) 打开, 有时要在新tab 打开. 例如个人信息页里除了修改姓名/头像等, 还可以认证身份. 用户任意浏览时如果想修改个人信息可能会在当前tab 打开个人信息页, 但用户在某业务页面操作到一半发现要认证身份, 那么通常应该在新tab 打开个人信息页.
那么在个人信息页完成修改或认证后, 需要history.back 还是window.close 呢?
在去到个人信息页的链接上加参数. 例如 ?open=local 在当前tab 打开, ?open=new 在新tab 打开. 个人信息页完成操作后判断: 如果local 则history.back, 如果new 则window.close.
但是用户在点链接的同时可以按Ctrl 键来强制在新tab 打开. 如此local 可能在新tab 打开, 那么history.back(mdn) 会没有效果 - 仍然停留在原地.
反之, 用户也可以复制new 的链接(到地址栏) 在当前tab 打开它, 那么window.close 可能令用户吃惊地把当前浏览器窗口关闭了, 也可能由于不满足条件(mdn) 而没有效果 - 仍然停留在原地.
无法假定个人信息页是在原tab 还是新tab 打开, 更好的方式应该是判断: 如果当前是新开则close, 否则是在原tab - 其history 里一定有多项 - 则back.
function backOrX() {
if (history.length >= 2) history.back();
else window.close();
}
实测发现上面的逻辑有个漏洞: 如果用户在新tab 打开个人信息页, 但是好奇点到了其他页面再退回个人信息页. 此时history 里有2 项, 但因为当前在第一项没有更前一项了, 所以history.back 仍然没有效果.
如此来看history 里无论有1项还是多项, 都可能要close, 但history api 又不提供查询当前项的位置, 怎么办?
一般的用户由于不太熟悉电脑操作, 打开的tab 应该是少比多好. 尤其是在手机这种小屏幕设备上, 例如微信浏览器似乎就始终只有一个tab.
所以我们把逻辑重新明确为: 能回退则回退, 否则才关闭.
再回头推敲代码, 终于有新发现: 如果history.back 生效, 那么当前页面就不再是包含此 backOrX 方法的页面 - 换句话说我们实现了回退. 如果不生效, 那么就还是在原页面上 - 可以继续关闭:
function backOrX() {
history.back();
window.close(); // trick
}
由于history.back 是异步的, 将window.close 也改成异步调用:
function backOrX() {
history.back();
window.setTimeout(window.close, 0); // trick
}
上面setTimeout 的第二个参数值0 是否一定能保证close 在back 之后调用未深入研究, 在Chrome/Firefox/微信下验证可以.
如前所述, 不满足条件时window.close 会没有效果, 包括微信浏览器总是禁止脚本关闭窗口.
既不能back 也不能close 例如双击个人信息页的快捷方式来直接打开, 又如点击微信对话里的该链接直接打开.