如何在多HTML页面间共享JavaScript的myNamespace命名空间变量?
首先得明确一个核心问题:每个浏览器标签页/窗口都是独立的JavaScript执行上下文,你引入的JS文件会在每个页面加载时重新执行一遍,所以每个页面里的myNamespace都是全新的实例,自然没法共享数据。下面给你几个适合新手的同源页面解决方案(如果是跨域页面,限制会多很多,先假设你的页面都是同一个域名下的):
方法1:通过窗口引用传递命名空间
如果你的其他页面都是从index.html打开的(比如用window.open()),可以直接把index.html里的myNamespace传递给新窗口:
在index.html里打开新窗口的代码改成这样:
// 打开新窗口 const newWindow = window.open('other.html'); // 等新窗口加载完成后,把当前的命名空间赋值给它的全局变量 newWindow.onload = function() { newWindow.myNamespace = myNamespace; };
这样在other.html里,你使用的myNamespace就和index.html里的是同一个对象了,操作数组的话两边都会同步。
如果是iframe嵌套的页面,直接用window.parent.myNamespace就能访问父页面的命名空间,不用额外赋值。
方法2:用Broadcast Channel API跨页面同步状态
如果你的页面不是通过index.html打开的(比如用户直接输入URL打开),可以用Broadcast Channel API实现同源页面之间的通信,同步窗口列表:
在所有页面的JS里都加上这段代码:
var myNamespace = myNamespace || {}; myNamespace.windows = []; // 创建一个名为"window-tracker"的广播通道 const windowChannel = new BroadcastChannel('window-tracker'); // 监听其他页面发来的消息 windowChannel.onmessage = function(event) { if (event.data.type === 'add-window') { // 这里注意:窗口对象无法跨上下文传递,所以我们可以存窗口的唯一标识(比如name) const existingWindow = myNamespace.windows.find(win => win.name === event.data.windowName); if (!existingWindow) { // 通过name获取窗口引用 const winRef = window.open('', event.data.windowName); myNamespace.windows.push(winRef); } } }; // 封装打开新窗口的函数 function openTrackedWindow(url) { // 给新窗口设置唯一name const windowName = `tracked-win-${Date.now()}`; const newWin = window.open(url, windowName); // 添加到当前页面的列表 myNamespace.windows.push(newWin); // 通知其他页面添加这个窗口 windowChannel.postMessage({ type: 'add-window', windowName: windowName }); }
以后打开新窗口都用openTrackedWindow(),所有同源页面的myNamespace.windows都会同步更新。
为什么你的原代码只在index.html生效?
因为每个页面加载时,JS文件会重新执行var myNamespace = myNamespace || {};——在index.html里第一次执行时myNamespace不存在,所以创建新对象;但在其他页面里,执行这句时也是创建全新的对象,和index.html里的完全没关系,自然看不到index.html里添加的窗口。
内容的提问来源于stack exchange,提问作者David AK

