如果我在同一个域中打开了两个(或更多)选项卡,是否有一种简单的方法来检测另一个选项卡的存在,(以便控制我的计算)?我知道有一个window.open()函数,但我没有打开另一个窗口。相反,想象一下用户有两个选项卡到mydomain.com。
我已经开始编写一些使用HTML5本地存储的代码,我会定期留下消息和检查消息,但这看起来有点令人费解。
答案 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非常相似,这只是一个本地套接字。
-
答案 2 :(得分:-1)
使用html5会话存储,您可以在窗口之间共享数据,这样您就可以在每次打开给定域的窗口时增加会话存储变量。