检测同一域的其他选项卡/窗口的存在

时间:2012-03-06 01:53:33

标签: javascript html html5 cross-browser

如果我在同一个域中打开了两个(或更多)选项卡,是否有一种简单的方法来检测另一个选项卡的存在,(以便控制我的计算)?我知道有一个window.open()函数,但我没有打开另一个窗口。相反,想象一下用户有两个选项卡到mydomain.com。

我已经开始编写一些使用HTML5本地存储的代码,我会定期留下消息和检查消息,但这看起来有点令人费解。

3 个答案:

答案 0 :(得分:3)

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

假设您打开了1个标签,并且“tabs_opened”localStorage计数器为1.出于某种原因,您必须强制退出浏览器。当您重新打开浏览器并重新访问同一网站时,“tabs_opened”计数器现在将变为2,因为“tabs_opened”计数器未递减。

我很抱歉我所说的不完全是答案(但我无法添加评论,因为我没有足够的声誉来添加评论)。我真的想指出这个边缘案例。

答案 1 :(得分:1)

那是一个有趣的问题。

我们可以尝试使用这些api: postMessage,sessionStorage,localStorage,webRtc

BroadcastChannel非常适合:

  

BroadcastChannel允许来自相同来源但其他来源的脚本   浏览上下文(窗口,工作人员)以互相发送消息。

     

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

与postMessage api的不同之处在于,子窗口并非要在父页面中声明。这样,不再有父母也没有孩子。

发送示例:

   function resourceEditor(container, options) {
            var selectedValues = [];
            var multiSelectData= options.model.multiSelectData;
            if (multiSelectData.length > 0) {
                selectedValues = multiSelectData.map(function (item) {
                    return item.id;
                });
            }

            $('<input id="multiSelect" name="' + options.field + '"/>')
                .appendTo(container)
                .kendoMultiSelect({
                    autoBind: false,
                    dataTextField: "name",
                    dataValueField: "id",
                    dataSource: _myData,
                    filter: "contains",
                    placeholder: "Select Values to Associate...",
                    value: selectedValues,
                    valuePrimitive: true,
                    dataBound: function () {
                        if (multiSelectData.length > 0) {
                            var fieldValues = multiSelectData.map(function (item) {
                                return item.id;
                            });
                            this.value(fieldValues);
                        }
                    },
                    autoClose: false
                });
        }

示例接收:

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

这样,我们可以计数选项卡,甚至可以将当前活动状态告知其他选项卡,等等。

- ( 2019年4月自此发布以来的使用情况反馈。 BroadcastChannel API非常简单,但是可以重新考虑架构

这允许import模块彼此对话,从而简化了脚本的构成。

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

可以随时查看内存使用情况和性能。我们可以创建许多并行传输大量数据流的通道,这对ram / cpu和接口响应能力没有影响。

变量少,逻辑少,广播的数据直接被废弃。编码样式与websockets非常相似,这只是一个本地套接字。

-

Broadcast_Channel_API

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

答案 2 :(得分:-1)

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