【问题标题】:Detect presence of other tabs / windows of same domain检测相同域的其他选项卡/窗口的存在
【发布时间】:2021-11-13 02:09:42
【问题描述】:

如果我在同一个域中打开了两个(或更多)选项卡,是否有一种简单的方法可以感知另一个选项卡的存在(以便控制我执行的计算)?我知道有一个 window.open() 函数,但我没有从另一个窗口打开一个窗口。相反,假设用户使用两个标签访问 mydomain.com。

我已经开始使用 HTML5 本地存储编写一些代码,我会定期在其中留下消息并检查消息,但这似乎有点令人费解。

【问题讨论】:

  • 您能找到解决方案吗?

标签: javascript html cross-browser


【解决方案1】:

这是一个有趣的问题。

我们可以尝试这些 api: postMessage、sessionStorage、localStorage、webRtc。


BroadcastChannel 非常适合:

BroadcastChannel 允许来自同一来源但其他来源的脚本 浏览上下文(windows、workers)以相互发送消息。

BroadcastChannel 接口代表一个命名频道,任何 给定来源的浏览上下文可以订阅。它允许 不同文档之间的通信(在不同的窗口、标签、 相同来源的框架或 iframe)。消息通过一个广播 在侦听的所有 BroadcastChannel 对象上触发的消息事件 频道。

它与 postMessage api 的不同之处在于子窗口不打算在父页面中声明。这样就没有父母和孩子了。

发送示例:

new BroadcastChannel('myapp').postMessage('Hello?');

接收示例:

new BroadcastChannel('myapp').addEventListener('message', function(e){
  console.log(e.data) 
})

这样,我们可以统计标签页,甚至可以将当前的活跃状态告知其他标签页等。

自此帖子以来的使用反馈。 BroadcastChannel api 非常简单,但允许重新思考架构。

这允许import 模块相互通信,这简化了脚本的组合。

我不觉得需要 webpacked 组合脚本来构建复杂的东西。我们可以通过通道共享对象(以 json 编码),在需要时调用“服务”,分离逻辑、模板、工厂、事件、服务,更容易。

这是针对内存使用和性能的。我们可以创建多个通道并行馈送一些大数据流,这对 ram/cpu 和接口响应能力几乎没有影响。

变量少,逻辑少,广播的数据被直接丢弃。编码风格与 websockets 非常相似,event-driven,这只是本地套接字。

事件驱动架构 (EDA) 是一种软件架构范式 促进生产、检测、消费和反应 事件。


[MDN] Broadcast_Channel_API

https://caniuse.com/#feat=broadcastchannel

【讨论】:

    【解决方案2】:

    在 localStorage 中设置一个计数器(打开一个新选项卡时增加计数器)并在关闭选项卡时依赖 onbeforeunload 减少计数器不是一个可靠的解决方案,因为如果你强制退出浏览器,onbeforeunload 监听器将不会执行,因此计数器不会递减。

    假设您打开了 1 个选项卡,并且您的“tabs_opened”localStorage 计数器为 1。由于某种原因,您必须强制退出浏览器。当您重新打开浏览器并重新访问同一网站时,“tabs_opened”计数器现在将变为 2,因为“tabs_opened”计数器没有减少。

    很抱歉,我所说的并不完全是一个答案(但我无法添加评论,因为我没有足够的声誉来添加评论)。我真的很想指出这种极端情况。

    【讨论】:

      【解决方案3】:

      使用html5会话存储,可以在窗口之间共享数据,这样每次打开给定域的窗口时,可以增加一个会话存储变量。

      【讨论】:

      • 好的,但是假设窗口 1 出现,我的变量 numWindows 现在是 1。窗口 2 出现并且 numWindows = 2。如果窗口 1 关闭,我无法减少,因为我无法预测何时会发生,因此我的计数器将关闭。
      • 或者我可以使用存储事件?
      • 您可以使用事件 window.onbeforeunload 来检测窗口何时关闭,因此您可以在那一刻执行一些代码。
      • 我检查了这个。 1. sessionStorage受限于特定的浏览器窗口,所以必须使用localStorage。还有可能出现竞争条件,即对 localStorage 的更新不是原子的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-02
      相关资源
      最近更新 更多