51

我需要能够识别我在浏览器中的哪个选项卡。我不能从浏览器中获得一些信息来识别标签吗?我不需要知道任何其他选项卡的任何信息,我只需要我所在选项卡的 id。它可以是随机数或序列号,也可以是日期时间戳,只要它在标签的寿命。

我有一个客户端应用程序,它通过 HTTP 连接到远程服务器,如果我在多个选项卡中打开它,每个实例都需要自己的唯一 ID,否则应用程序会失败,所以我只需要一些与只要该选项卡存在(即当我浏览提供此应用程序的网站时页面刷新后仍然存在的内容),该选项卡就会存在。似乎很简单,应该只在浏览器中可用,例如 window.tabId - 这就是我所需要的。我有一个严重的开发障碍,因为我无法通过这个看似不存在的简单、简单、简单的解决方案。必须有一种方法(一种跨浏览器的解决方案)。

有任何想法吗?

4

10 回答 10

51

SessionStorage 是每个选项卡/窗口的,因此您可以在 sessionStorage 中定义一个随机数,如果存在则首先获取它:

var tabID = sessionStorage.tabID ? 
            sessionStorage.tabID : 
            sessionStorage.tabID = Math.random();

更新
在某些情况下,您可能在多个选项卡中拥有相同的 sessionStorage(例如,当您复制选项卡时)。在这种情况下,以下代码可能会有所帮助:

var tabID = sessionStorage.tabID && 
            sessionStorage.closedLastTab !== '2' ? 
            sessionStorage.tabID : 
            sessionStorage.tabID = Math.random();
sessionStorage.closedLastTab = '2';
$(window).on('unload beforeunload', function() {
      sessionStorage.closedLastTab = '1';
});
于 2016-04-23T07:14:01.393 回答
15

您必须使用 html5,但sessionStorage与随机 guid 相结合似乎是您想要的。

于 2012-08-10T06:39:05.340 回答
9

这是一种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;
});

访问tabId使用window.tabId.

需要该beforeunload事件才能使tabId刷新后具有相同的可用 ID。

load活动需要:

  1. 生成初始tabId.
  2. tabId刷新后加载相同- 如果存在。

* 我真的不知道为什么我应该这样做return null或返回。只需阅读不返回可能会导致该功能无法正常工作:(

于 2020-02-11T07:46:00.760 回答
9

由于我没有找到简单的 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 模板进行开发,因此仅在一个地方定义了 :-)

于 2018-09-07T08:26:16.243 回答
6

您无法使用 javascript 获取标签 ID,但是有一些解决方案可以帮助您在用户打开新标签时使用不同的会话/cookie。

一些参考:

获取浏览器标签索引/ID

从火狐扩展获取火狐标签的网址

如何在浏览器选项卡中区分会话?

在每个浏览器选项卡中获取唯一会话

asp.net - 会话 - 多个浏览器选项卡 - 不同的会话?

于 2012-08-10T06:00:23.097 回答
3

对于这里使用 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
}

把它放在你的基础 App/Page 组件上,或者你知道会一直挂载的地方。

它会在挂载后运行效果,并为会话存储中的当前选项卡设置一个唯一的 id,该选项卡是特定于选项卡的存储。

复制选项卡将为您提供新选项卡的新 ID,因为组件将再次安装并且效果将运行,覆盖前一个选项卡的 ID

于 2019-07-24T22:14:40.830 回答
2

一种可能的解决方案是使用“window.name”属性,但我不想使用它,因为其他人可以使用它。

我找到了另一种可能的解决方案:使用 sessionStorage。FF3.5+、Chrome4+、Safari4+、Opera10.5+、IE8+支持。

于 2012-09-18T14:17:20.900 回答
1

如果用户在 2 毫秒内打开 3 个选项卡的可能性不大,则可以使用时间戳并将其存储到 window.name 中,并将其用作查找中的键。window.name 值将保留在选项卡中,直到它关闭。

时间戳

于 2017-07-12T13:37:47.803 回答
0

您可以在服务人员的“获取”事件处理程序中获取选项卡 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()

于 2021-04-19T08:45:14.653 回答
-1

至少对于 chrome,自 2013 年以来就有一个官方答案: chrome.tabs API

于 2018-07-09T15:40:04.560 回答