在 JavaScript 中识别浏览器选项卡的任何方法
Any way to identify browser tab in JavaScript?
我需要能够识别我在浏览器中的哪个选项卡中。 我不能从浏览器中获得一些信息来识别选项卡吗? 我不需要知道任何其他选项卡,我只需要我所在的选项卡的 ID。它可以是随机或序列数字,也可以是日期时间戳,只要它在选项卡的生命周期内保持不变即可。
我有一个客户端应用程序,它通过 HTTP 连接到远程服务器进行 BOSH,如果我在多个选项卡中打开它,每个实例都需要自己的唯一 ID 或应用程序失败,所以我只需要一些与选项卡相关联的唯一编号,只要该选项卡存在(即当我浏览提供此应用程序的网站时,页面刷新后仍然存在的东西)。 似乎应该在浏览器中可用,例如window.tabId - 这就是我所需要的。 我有一个严重的开发障碍,因为我无法克服这个似乎不存在的简单,简单,简单的解决方案。 必须有一种方法(跨浏览器解决方案)。
有什么想法吗?
SessionStorage 是按选项卡/窗口进行的,因此您可以在 sessionStorage 中定义一个随机数,如果存在,请先获取它:
var tabID = sessionStorage.tabID ?
sessionStorage.tabID :
sessionStorage.tabID = Math.random();
更新:
在某些情况下,您可能在多个选项卡中具有相同的会话存储(例如,当您复制选项卡时)。在这种情况下,以下代码可能会有所帮助:
var tabID = sessionStorage.tabID &&
sessionStorage.closedLastTab !== '2' ?
sessionStorage.tabID :
sessionStorage.tabID = Math.random();
sessionStorage.closedLastTab = '2';
$(window).on('unload beforeunload', function() {
sessionStorage.closedLastTab = '1';
});
您必须使用 html5,但 sessionStorage 与随机 guid 相结合似乎是您想要的。
加载页面后使tabId
可用的方法 - 即使在刷新后也具有相同的tabId
。
这也解决了重复选项卡的问题,因为tabId
已从sessionStorage
中清除。
window.addEventListener("beforeunload", function (e)
{
window.sessionStorage.tabId = window.tabId;
return null;
});
window.addEventListener("load", function (e)
{
if (window.sessionStorage.tabId)
{
window.tabId = window.sessionStorage.tabId;
window.sessionStorage.removeItem("tabId");
}
else
{
window.tabId = Math.floor(Math.random() * 1000000);
}
return null;
});
使用 window.tabId
访问tabId
。
需要 beforeunload
事件才能使tabId
在刷新后具有相同的 id 可用。
load
事件需要:
- 生成初始
tabId
。 - 刷新后加载相同的
tabId
(如果存在)。
*我真的不知道为什么我应该做return null
或返回。只需阅读不返回可能会导致函数无法工作:(
我没有找到简单的Javascript函数作为windows.currentTabIndex
,我编写了一些Javascript行来修复加载每个浏览器选项卡时的ID。
function defineTabID()
{
var iPageTabID = sessionStorage.getItem("tabID");
// if it is the first time that this page is loaded
if (iPageTabID == null)
{
var iLocalTabID = localStorage.getItem("tabID");
// if tabID is not yet defined in localStorage it is initialized to 1
// else tabId counter is increment by 1
var iPageTabID = (iLocalTabID == null) ? 1 : Number(iLocalTabID) + 1;
// new computed value are saved in localStorage and in sessionStorage
localStorage.setItem("tabID",iPageTabID);
sessionStorage.setItem("tabID",iPageTabID);
}
}
此代码将最后一个选项卡的索引保存在localStorage
以更新新选项卡的当前值,并在sessionStorage
中保存以修复页面的 id!
我必须在应用程序的每一页中调用defineTabId()
函数。由于我使用 JSF 模板进行开发,因此仅在一个地方定义了 :-)
您无法使用 javascript 获取选项卡 ID,但是有一些解决方案可以帮助您,例如在用户打开新选项卡时使用不同的会话/cookie。
一些参考:
获取浏览器选项卡索引/ID
从火狐扩展获取火狐标签的网址
如何区分浏览器选项卡中的会话?
在每个浏览器选项卡中获取唯一的会话
asp.net - 会话 -多个浏览器选项卡 - 不同的会话?
对于这里使用 React 的任何人,我做了一个偷偷摸摸的小钩子:
import {useEffect, useMemo} from 'react'
import uniqid from 'uniqid'
export const TAB_ID_KEY = 'tabId'
export default () => {
const id = useMemo(uniqid, [])
useEffect(() => {
if (typeof Storage !== 'undefined') {
sessionStorage.setItem(TAB_ID_KEY, id)
}
}, [id])
return id
}
把它放在你的基本应用程序/页面组件上,或者放在你知道将永远挂载的地方。
它将在挂载后运行效果,并为会话存储中的当前选项卡设置唯一 ID,这是特定于选项卡的存储。
复制选项卡将获得新选项卡的新 id,因为组件将再次挂载并且效果将运行,覆盖上一个选项卡的 id
可能的解决方案之一是使用"window.name"属性,但我不想使用它,因为其他人可以使用它。
我找到了另一种可能的解决方案:使用sessionStorage。FF3.5+、Chrome4+、Safari4+、Opera10.5+和IE8+支持它。
您可以在服务工作线程的"fetch"事件处理程序中获取选项卡 ID(或 clientId)。如果您需要将该clientId发送到您的页面,只需使用client.postMessage()。
在服务辅助角色中:
self.addEventListener("fetch", function(event) {
event.waitUntil(async function() {
if (!event.clientId) return;
const client = await clients.get(event.clientId);
if (!client) return;
client.postMessage({
clientId: event.clientId,
});
}());
});
在页面脚本中:
navigator.serviceWorker.addEventListener('message', event => {
console.log(event.data.clientId);
});
来源:Client.postMessage()
如果用户在 2 毫秒内打开 3 个选项卡的几率不高,可以使用时间戳并将其存储到 window.name 中,并将其用作查找中的键。window.name 值将保留在选项卡中,直到它关闭。
时间戳
主题的另一个变体:将其放在HTML的head部分
<head><script>
var tabId=sessionStorage.getItem("tabId");
if (!tabId||(tabId!==sessionStorage.getItem("tabClosed"))){
tabId=Math.random().toString(36).substr(2)+Date.now().toString(36).substr(5);
sessionStorage.setItem("tabId",tabId);
}
sessionStorage.removeItem("tabClosed");
window.addEventListener("unload",function(){
sessionStorage.setItem("tabClosed",tabId);
});
document.title=tabId;
</script></head>
工作原理:
首先,通过将其放在头部,它会立即解析 tabId,因此任何加载脚本都可以访问 tabId,以防这对您很重要。
当页面加载时,从新选项卡上的会话存储读取将意味着tabId为空,在这种情况下,将发明一个新的id。
每当关闭选项卡时,都会写入 tabClosed 值,并在重新加载选项卡时立即将其删除。
当您复制选项卡时,会话信息将被复制,因此,tabClosed 值将不存在,因此也会发明一个新的 id。
使用 sessionStorage
查看所有更复杂的答案
.. 为什么不直接使用当前时间?
var timeId = new Date().getTime();
从OP:
"它可以是一个随机或序列的数字,或者一个日期时间戳,只要它在选项卡的生命周期内保持不变。
至少对于chrome来说,自2013年以来有一个官方答案:chrome.tabs API。
- 有没有任何方法可以将控制器从文件加载到ui路由器$stateProvider中
- 是否有任何方法可以使用jQuery替换在数组中定义值的文本
- 在D3.js中,有没有任何方法可以将x和y方向上的滚动事件绑定到平移svg
- 有没有任何方法可以使用node-js从不同的机器打开浏览器
- PhantomJS - 检查javascript函数是否正在运行的任何方法
- 在不重新加载的情况下更改标头URL的任何方法
- 在离子2中,有任何方法可以将涡旋动量作为一个事件来检测
- 有没有任何方法可以将javascript对象从源代码传递到系统/浏览器剪贴板
- 在jquery中是否有任何方法或位置可以编写从Dom中删除页面后调用的方法
- 使用多功能框在 chrome 扩展程序中包含内联自动填充功能的任何方法
- 在 JavaScript 中识别浏览器选项卡的任何方法
- 是从画布获取图像数据的任何方法,从远程视频中提取
- Win7 IE9 youtube播放器js对象没有任何方法
- 是否有任何方法适用于“WebGLRenderingContext”,如“CanvasRenderingContext2D
- 是否有任何方法可以去除“"打印时从阵列中删除
- 是否有任何方法可以像HTML5<p>标签
- Vue.js路由未处理任何方法
- 有没有任何方法可以将json对象存储在HTML标记的默认/自定义属性中,比如<tr>
- 是否有任何方法可以避免使用JSDoc“@方法“;注释
- 有没有任何方法可以从javascript进行跨域请求,并访问它可能生成的错误响应类型(401404等)