在 JavaScript 中识别浏览器选项卡的任何方法

Any way to identify browser tab in JavaScript?

本文关键字:任何 方法 选项 浏览器 JavaScript 识别      更新时间:2023-09-26

我需要能够识别我在浏览器中的哪个选项卡中。 我不能从浏览器中获得一些信息来识别选项卡吗? 我不需要知道任何其他选项卡,我只需要我所在的选项卡的 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事件需要:

  1. 生成初始tabId
  2. 刷新后加载相同的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。

相关文章: